2009-01-12 8 views
24

Die folgende Abfrage wird alle Dewey Dezimalzahlen angezeigt, die in der „Buch“ Tabelle dupliziert wurden:Wie finde ich doppelte Einträge in einer Datenbanktabelle?

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

jedoch, was ich tun möchte meine Abfrage die Namen der Autoren angezeigt haben im Zusammenhang mit der duplizierte Eintrag (die Tabelle "book" und die Tabelle "author" sind mit "author_id" verbunden). Mit anderen Worten, ergäbe die Abfrage über die folgenden:

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

Was ich zur Anzeige der Ergebnisse der folgenden ist etwas Ähnliches möchte:

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

Jede Hilfe Sie stark zur Verfügung stellen kann geschätzt . Und wenn es ins Spiel kommt, benutze ich eine Postgresql DB.

UPDATE: Bitte beachten Sie, dass "author_last_name" nicht in der "Buch" -Tabelle ist.

+0

Duplikat von http://stackoverflow.com/questions/18932/sql-how-can-i-remove-duplicate-rows Kann jemand bitte schließen? –

+5

Lesen Sie es genauer. Dies ist kein Duplikat. – Huuuze

+0

Kein Duplikat. Er möchte die doppelten Zeilen (und mehr davon) finden, nicht um sie zu entfernen. –

Antwort

21

Eine verschachtelte Abfrage, um den Job tun.

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 

(. Ich weiß nicht, ob dies der schnellste Weg ist, zu erreichen, was Sie wollen)

Update: Hier ist meine Daten

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 

Und hier ist das Ergebnis der obige Abfrage:

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

Ok, wahrscheinlich ist eine verschachtelte Abfrage übertrieben, aber jetzt bin ich mir sicher, dass es funktioniert. Der Kommentar von Tony Andrews zur Spalte author_id gilt auch hier. –

+0

Übrigens, warum suchen Sie nach Duplikaten basierend auf dem Namen des Autors und Dewey-Code? Duplikate (mehrere Kopien des gleichen Buches, denke ich) sollten auch auf dem Buchtitel basieren ... –

+0

Ich habe den Code aktualisiert, aber er gibt 0 Ergebnisse zurück. Was die Use-Case-Frage betrifft, habe ich einfach ein Dummy-Szenario erstellt - ich arbeite nicht wirklich daran, doppelte Bücher zu entdecken. – Huuuze

20

Sie wollen wahrscheinlich diese

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" ist nicht in der "Buch" -Tabelle. Die Tabelle "book" und die Tabelle "author" sind durch ein FKed "author_id" in der Tabelle "book" verbunden. – 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 

Wenn Buch. author_id kann null sein dann die Verbindung ändern:

LEFT OUTER JOIN author USING (author_id) 

Wenn die author_id Spalte einen anderen Namen in jeder Tabelle hat dann verwenden Sie können nicht verwenden, benutzen Sie ON statt:

JOIN author ON author.id = book.author_id 

oder

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

Kein Glück auf diesem. Es gibt 0 Ergebnisse zurück. – Huuuze

+0

Haben beide Tabellen eine Spalte AUTHOR_ID, wie Sie angegeben haben? Meine USING-Syntax setzt dies voraus. Wenn nicht, wechseln Sie zu "JOIN author ON author.xxx = book.yyy". Wenn die Abfrage 0 Zeilen (ohne Fehler) zurückgibt, die darauf hindeuten, dass dort die Tabelle authors leer ist? –

+0

Ich denke, wir kommen näher. Ich habe es vernachlässigt zu erwähnen, dass es "author.id" und "book.author_id" ist, also guten Ruf auf USING vs ON. Ich habe dementsprechend aktualisiert, aber Postgresql mochte nicht die Klammer "[LINKER JOIN]". Nach dem Entfernen der Klammern ergeben sich 0 Ergebnisse. – 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

Zusätzlich zur Bereitstellung von Code, können Sie auch erklären, warum diese Antwort funktioniert? –

+0

Sie werden einen Fehler erhalten, weil autor_last_name nicht in der Gruppe von oder in einer Aggregatfunktion ist. –

0

Die meisten einfachen und efective Weg gefunden, i ist unten gezeigt:

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