2009-01-12 15 views
24

La siguiente consulta se mostrarán todos los números Decimal Dewey que han sido duplicados en la tabla de "libro":¿Cómo puedo encontrar entradas duplicadas en una tabla de base de datos?

SELECT dewey_number, 
COUNT(dewey_number) AS NumOccurrences 
FROM book 
GROUP BY dewey_number 
HAVING (COUNT(dewey_number) > 1) 

Sin embargo, lo que me gustaría hacer es tener mi consulta muestra el nombre de los autores asociados con la entrada duplicada (la tabla "libro" y la tabla "autor" están conectadas por "author_id"). En otras palabras, la consulta anterior produciría lo siguiente:

dewey_number | NumOccurrences 
------------------------------ 
5000   | 2 
9090   | 3 

lo que me gustaría los resultados visualizar sea algo similar a lo siguiente:

author_last_name | dewey_number | NumOccurrences 
------------------------------------------------- 
Smith   | 5000   | 2 
Jones   | 5000   | 2 
Jackson   | 9090   | 3 
Johnson   | 9090   | 3 
Jeffers   | 9090   | 3 

Cualquier ayuda que puede proporcionar es muy apreciada . Y, en caso de que entre en juego, estoy usando una base de datos Postgresql.

ACTUALIZACIÓN: Tenga en cuenta que "author_last_name" no está en la tabla "libro".

+0

Duplicado de http://stackoverflow.com/questions/18932/sql-how-can-i-remove-duplicate-rows ¿Alguien puede cerrar por favor? –

+5

Léelo más de cerca. Esto no es un duplicado – Huuuze

+0

No es un duplicado en absoluto. Él quiere * encontrar * las filas duplicadas (y más que eso), no para eliminarlas. –

Respuesta

21

Una consulta anidada puede hacer el trabajo.

SELECT author_last_name, dewey_number, NumOccurrences 
FROM author INNER JOIN 
    (SELECT author_id, dewey_number, COUNT(dewey_number) AS NumOccurrences 
     FROM book 
     GROUP BY author_id, dewey_number 
     HAVING (COUNT(dewey_number) > 1)) AS duplicates 
ON author.id = duplicates.author_id 

(. No sé si esta es la manera más rápida de lograr lo que quiere)

Actualización: Aquí es mis datos

SELECT * FROM author; 
id | author_last_name 
----+------------------ 
    1 | Fowler 
    2 | Knuth 
    3 | Lang 

SELECT * FROM book; 
id | author_id | dewey_number |   title   
----+-----------+--------------+------------------------ 
    1 |   1 |   600 | Refactoring 
    2 |   1 |   600 | Refactoring 
    3 |   1 |   600 | Analysis Patterns 
    4 |   2 |   600 | TAOCP vol. 1 
    5 |   2 |   600 | TAOCP vol. 1 
    6 |   2 |   600 | TAOCP vol. 2 
    7 |   3 |   500 | Algebra 
    8 |   3 |   500 | Undergraduate Analysis 
    9 |   1 |   600 | Refactoring 
10 |   2 |   500 | Concrete Mathematics 
11 |   2 |   500 | Concrete Mathematics 
12 |   2 |   500 | Concrete Mathematics 

Y aquí es el resultado de la consulta anterior:

author_last_name | dewey_number | numoccurrences 
------------------+--------------+---------------- 
Fowler   |   600 |    4 
Knuth   |   600 |    3 
Knuth   |   500 |    3 
Lang    |   500 |    2 
+0

Ok, probablemente una consulta anidada es exagerada, pero ahora estoy seguro de que funciona. El comentario de Tony Andrews sobre la columna author_id también se aplica aquí. –

+0

Por cierto, ¿por qué estás buscando duplicados basados ​​en el nombre del autor y el código Dewey? Duplicados (varias copias del mismo libro, supongo) deberían basarse también en el título del libro ... –

+0

Actualicé el código, pero devuelve 0 resultados. En cuanto a la pregunta del caso de uso, simplemente creé un escenario ficticio: en realidad no estoy trabajando en la detección de libros duplicados. – Huuuze

20

es probable que desee este

SELECT dewey_number, author_last_name, 
COUNT(dewey_number) AS NumOccurrences 
FROM book 
GROUP BY dewey_number,author_last_name 
HAVING (COUNT(dewey_number) > 1) 
+1

"author_last_name" no está en la tabla "libro". La tabla "libro" y la tabla "autor" están conectadas por un "author_id" FKed en la tabla "libro". – Huuuze

2
SELECT dewey_number, author_last_name, 
     COUNT(dewey_number) AS NumOccurrences 
FROM book 
JOIN author USING (author_id) 
GROUP BY dewey_number,author_last_name 
HAVING COUNT(dewey_number) > 1 

Si el libro. author_id puede ser nulo a continuación, cambiar la combinación de:

LEFT OUTER JOIN author USING (author_id) 

Si la columna de la author_id tiene un nombre diferente en cada mesa, entonces no se puede utilizar USO, EN utilizar en su lugar:

JOIN author ON author.id = book.author_id 

o

LEFT OUTER JOIN author ON author.id = book.author_id 
+0

Sin suerte en este caso. Devuelve 0 resultados. – Huuuze

+0

¿Ambas tablas tienen una columna AUTHOR_ID como usted indicó? Mi sintaxis de USO asume eso. Si no, cambie a "JOIN author ON author.xxx = book.yyy". Si la consulta devuelve 0 filas (sin error), ¿eso sugiere que la tabla de autores está vacía? –

+0

Creo que nos estamos acercando. Me olvidé de mencionar que es "author.id" y "book.author_id", así que bien llame al USING vs ON. Actualicé en consecuencia, pero a Postgresql no le gustó el corchete "[IZQUIERDA]". Después de eliminar los corchetes, arroja 0 resultados. – Huuuze

0
select author_name,dewey_number,Num_of_occur 
from author a,(select author_id,dewey_number,count(dewey_number) Num_of_occur 
       from book 
       group by author_id,dewey_number 
       having count(dewey_number) > 1) dup 
where a.author_id = dup.author_id 
+0

Además de proporcionar el código, ¿también puede explicar por qué esta respuesta funcionará? –

+0

Recibirá un error porque author_last_name no está en el grupo por o en una función agregada. –

0

forma más sencilla y Efectiva he encontrado es muestra a continuación:

SELECT 
    p.id 
    , p.full_name 
    , (SELECT count(id) FROM tbl_documents as t where t.person_id = p.id) as rows 
FROM tbl_people as p 
WHERE 
    p.id 
IN (SELECT d.person_id FROM tbl_documents as d 
    GROUP BY d.person_id HAVING count(d.id) > 1) 
ORDER BY 
    p.full_name 
Cuestiones relacionadas