SQL – path, um doppelte Felder innerhalb mehrerer Zeilen zu finden?

Ich frage mich, ob es einen path gibt, um Duplikate von Teilen von Zeilen zurückzugeben.

IDTable-Setup:

ID# | Customer | EventID# 1 | Steve | 123 2 | Steve | 123 3 | John | 987 4 | John | 924 

Da Steve und 123 zweimal zusammen erscheinen, möchte ich das als 'Duplikat' behandeln, obwohl sie zwei verschiedene ID # 's haben. Und wenn es ein 'Duplikat' gibt, würde ich gern nur Spalten zurückgeben: ID #, Customer & EventID #. Also für das obige IDTable Beispiel, nur zurück:

 1 | Steve | 123 2 | Steve | 123 

Wenn Sie folgendes ausführen, zählt es jede ID + Kunde + EventID # separat und gibt alle Zählwerte als 1 zurück (ich verwende SQL server 2008):

 SELECT ID#, Customer, EventID#, COUNT({fn CONCAT(Customer,EventID#)}) FROM IDTable GROUP BY ID#, Customer, EventID# HAVING COUNT({fn CONCAT(Customer,EventID#)}) > 1 

Wenn ich die ID # aus der Select herausnehme, funktioniert es aber dann werden wir nicht wissen, was die ID # 's sind.

EDIT: Ich komme in die ausgewählten Spalten aus anderen Tabellen. Zuerst habe ich diese aus der Einfachheit halber verlassen, wenn ich versuche, Lösungen zu finden, die ich verwirren werde. Entschuldigung! Hier ist was im Einklang mit dem, was ich benutze:

 SELECT A.ID#, C.Customer, E.EventID# FROM IDTable A INNER JOIN CustomerTable C ON C.AccountID = A.AccountID INNER JOIN EventTable E ON E.AccountType = C.AccountType WHERE C.StatusID = 'Active' 

Self-Join sollte den Trick machen:

 SELECT A.ID#, A.Customer, A.EventID# FROM Table A INNER JOIN Table A2 ON A.Customer = A2.Customer AND A.EventID# = A2.EventID# AND A.ID# <> A2.ID# 

Bearbeiten Sie für Ihre Joins:

Du kannst immer noch eine Selbstverknüpfung benutzen, nur mit abgeleiteten Tabellen wie folgt:

 SELECT A.ID#, A.Customer, A.EventID# FROM (SELECT ID#, Customer, EventID# FROM IDTable A INNER JOIN CustomerTable C ON C.AccountID = A.AccountID INNER JOIN EventTable E ON E.AccountType = C.AccountType WHERE C.StatusID = 'Active') A INNER JOIN (SELECT ID#, Customer, EventID# FROM IDTable A INNER JOIN CustomerTable C ON C.AccountID = A.AccountID INNER JOIN EventTable E ON E.AccountType = C.AccountType WHERE C.StatusID = 'Active') A2 ON A.Customer = A2.Customer AND A.EventID# = A2.EventID# AND A.ID# <> A2.ID# 

Und sauberer mit #TEMP :

 SELECT A.ID#, C.Customer, E.EventID# INTO #TEMP FROM IDTable A INNER JOIN CustomerTable C ON C.AccountID = A.AccountID INNER JOIN EventTable E ON E.AccountType = C.AccountType WHERE C.StatusID = 'Active' ; SELECT A.ID#, A.Customer, A.EventID# FROM #TEMP A INNER JOIN #TEMP A2 ON A.Customer = A2.Customer AND A.EventID# = A2.EventID# AND A.ID# <> A2.ID# 

Die meisten Versionen der SQL-Support-windowsfunktionen. Der einfachste path, dies zu lösen, ist:

 select id, customer, eventid# from (select i.*, count(*) over (partition by customer, eventid#) as cnt from idtable i ) i where cnt > 1; 
 SELECT i.* FROM IDTable i INNER JOIN (SELECT Customer, EventID# FROM IDTable GROUP BY ID#, Customer, EventID# HAVING COUNT(*) > 1) t ON i.Customer = t.Customer AND i.EventId# = t.EventId# 

Es gibt andere Möglichkeiten, dies zu tun und wenn du deine spezifischen rdbms (sql-server, oracle, mysql etc.) kennst, bin ich sicher, dass du zusätzliche Antworten bekommst, aber hier ist eine Möglichkeit, es zu tun, was deine Abfrage verwenden soll (ohne die ID-Spalte), um die Duplikate zu identifizieren und sie dann über eine innere Verknüpfung wieder auf Ihren ursprünglichen Tisch zu übertragen.

Von @ Aaron_D Antwort würde ich nicht join Unterabfragen, stattdessen können Sie:

 SELECT A.ID#, C.Customer, E.EventID# FROM IDTable A INNER JOIN IDTable B ON A.ID# = B.ID# AND A.AccountID <> B.AccountID INNER JOIN CustomerTable C ON C.AccountID = A.AccountID INNER JOIN EventTable E ON E.AccountType = C.AccountType WHERE C.StatusID = 'Active' 

Da sowohl CustomerTable als auch EventTable in letzter Instanz von AccountID abgeleitet sind, wird es gut funktionieren und wird schneller sein.