2017-12-13 12 views
4

Ich habe eine Tabelle wie folgt aus:So gruppieren ähnliche Zeilen in SQL Server

Date  ConfigID ItemID ClientName Metric1 Metric2 
====  ======== ====== ========== ======= ======= 
2017-01-01 1   1   A    2.0  2.0 
2017-01-01 3   1   A    2.0  2.0 
2017-01-01 4   2   B    5.0  5.0 
2017-01-02 4   3   A    6.0  6.0 
2017-01-01 2   1   A    2.0  2.0 
.... 
(20 million rows here) 

ich die Duplikate hier basierend auf Date, ItemID, ClientName, Metric1 und Metric2, also schrieb ich erkennen wollte:

CREATE TABLE MyTable ([Date] date, 
         ConfigID int, 
         ItemID int, 
         ClientName char(1), 
         Metric1 decimal(3,1), 
         Metric2 decimal(3,1)); 
INSERT INTO MyTable 
VALUES ('2017-01-01',1,1,'A',2.0,2.0), 
     ('2017-01-01',3,1,'A',2.0,2.0), 
     ('2017-01-01',4,2,'B',5.0,5.0), 
     ('2017-01-02',4,3,'A',6.0,6.0), 
     ('2017-01-01',2,1,'A',2.0,2.0);  

WITH Dupes   
AS (   
    SELECT *   
     ,ROW_NUMBER() OVER ( 
      PARTITION BY 
       [Date] 
       ,[ItemID] 
       ,[ClientName] 
       ,[Metric1] 
       ,[Metric2] 
      ORDER BY [Date] DESC 
    ) AS RowNum 
    FROM myTable) 

SELECT * 
FROM Dupes 

Aber das gibt so etwas wie dieses:

Date  ConfigID ItemID ClientName Metric1 Metric2 RowNum 
====  ======== ====== ========== ======= ======= ====== 
2017-01-01 1   1   A    2.0  2.0  1 
2017-01-01 3   1   A    2.0  2.0  2 
2017-01-01 4   2   B    5.0  5.0  1 
2017-01-02 4   3   A    6.0  6.0  1 
2017-01-01 2   1   A    2.0  2.0  3 
.... 
(20 million rows here) 

Ich möchte die ähnlichen Artikel basierend auf der PARTITION BY Klausel gruppieren. Mit anderen Worten, würde Ich mag so etwas sehen (ich weiß nicht wirklich RowNum brauchen):

Date  ConfigID ItemID ClientName Metric1 Metric2 RowNum 
====  ======== ====== ========== ======= ======= ====== 
2017-01-01 1   1   A    2.0  2.0  1 
2017-01-01 3   1   A    2.0  2.0  2 
2017-01-01 2   1   A    2.0  2.0  3 
2017-01-01 4   2   B    5.0  5.0  1 
2017-01-02 4   3   A    6.0  6.0  1 
.... 
(20 million rows here) 

Abfrage Was SQL mir helfen Gruppe in einer Tabelle das Duplikat/ähnliche Zeilen würde? Vielen Dank im Voraus für Vorschläge und Antworten!

+0

Was meinst du mit "Gruppe" sie? Möchten Sie sie nicht in Ihrem Dataset zurückgeben? Aggragate sie? Etwas anderes? – Larnu

+0

@Larnu, ich meine, ich möchte sie manuell überprüfen, um zu sehen, wo die Dinge anders sind (z. B. kann ich sehen, wie viele verschiedene ConfigID die gleichen Werte in anderen Spalten haben). – user1330974

Antwort

1

Verwendung von DENSE_RANK anstelle von ROW_NUMBER könnte helfen?

;   
WITH Dupes   
AS (   
    SELECT *   
     ,DENSE_RANK () 
     OVER ( 
      ORDER BY 
       [Date] 
       ,[ItemID] 
       ,[ClientName] 
       ,[Metric1] 
       ,[Metric2]   
      DESC 
    ) AS GroupID 
    FROM myTable) 

SELECT * 
FROM Dupes 

hier die Lösung vorgeschlagen:

;   
WITH D1   
AS (   
    SELECT *   
     ,DENSE_RANK () 
     OVER ( 
      ORDER BY 
       [Date] 
       ,[ItemID] 
       ,[ClientName] 
       ,[Metric1] 
       ,[Metric2]   
      DESC 
    ) AS GroupID 
    FROM myTable) 
, Dupes AS (
    SELECT * 
     , COUNT(*) OVER (PARTITION BY GroupID) AS GroupItemsCount 
    FROM D1 
) 
SELECT * 
FROM Dupes 
WHERE GroupItemsCount <> 1 

aber eine bessere Art und Weise

;   
WITH Dupes   
AS (   
    SELECT *   
     ,COUNT(*) 
     OVER ( 
      partition BY 
       [Date] 
       ,[ItemID] 
       ,[ClientName] 
       ,[Metric1] 
       ,[Metric2]   
    ) AS GroupItemsCount 
    FROM myTable) 

SELECT * 
FROM Dupes 
WHERE GroupItemsCount > 1 
+0

Ja! 'DENSE_RANK' ist nah dran was ich wollte. Aber wie würde man die Daten mit ** mehr als einer Zeile ** in einem bestimmten Rang aus der obigen Abfrage extrahieren? Angenommen, drei Zeilen haben den Rang '1', den restlichen Zeilen ist ein eindeutiger Rang zugewiesen (2 ... n). Dann möchte ich nur den mit dem Rang '1' extrahieren/überprüfen. Welche zusätzliche Abfrage würde hier helfen? Vielen Dank! – user1330974

+1

Ich bin nicht hinter meinem PC, aber ich empfehle Ihnen, COUNT() OVER (PARTITION von GroupID) als GroupItemsCount in einem anderen CTE und Filter GroupItemsCount> 1 – Ezin82

+0

JA !! 'COUNT (*) OVER (PARTITION BY ....)' und Filterung basierend auf 'count> 1' und die Sortierung nach allen Kriterien innerhalb der 'PARTITION BY'-Klausel funktioniert !! Vielen Dank! – user1330974

1

gibt nur einen Auftrag von in der Auswahl

;   
WITH Dupes   
AS (   
    SELECT *   
     ,ROW_NUMBER() OVER ( 
      PARTITION BY 
       [Date] 
       ,[ItemID] 
       ,[ClientName] 
       ,[Metric1] 
       ,[Metric2] 
      ORDER BY [Date] DESC 
    ) AS RowNum 
    FROM myTable) 

SELECT * 
FROM Dupes 
order by [Date] 
       ,[ItemID] 
       ,[ClientName] 
       ,[Metric1] 
       ,[Metric2], 
RowNum 
1

Ich glaube, Sie nur order by brauchen. Und der CTE ist nicht notwendig:

. . . 
SELECT * 
FROM Dupes 
ORDER BY [Date], [ItemID], [ClientName], [Metric1], [Metric2]; 
1

Basierend Vorschlag auf Luca im Kommentar sein könnte, mit COUNT(*) PARTITION BY(...) scheint zu funktionieren:

CREATE TABLE MyTable ([Date] date, 
         ConfigID int, 
         ItemID int, 
         ClientName char(1), 
         Metric1 decimal(3,1), 
         Metric2 decimal(3,1)); 
INSERT INTO MyTable 
VALUES ('2017-01-01',1,1,'A',2.0,2.0), 
     ('2017-01-01',3,1,'A',2.0,2.0), 
     ('2017-01-01',4,2,'B',5.0,5.0), 
     ('2017-01-02',4,3,'A',6.0,6.0), 
     ('2017-01-01',2,1,'A',2.0,2.0);  

WITH Dupes   
AS (   
    SELECT *   
     ,COUNT(*) OVER ( 
      PARTITION BY 
       [Date] 
       ,[ItemID] 
       ,[ClientName] 
       ,[Metric1] 
       ,[Metric2] 
      ORDER BY [Date] DESC 
    ) AS DupeCount 
    FROM myTable) 

SELECT * 
FROM Dupes 
WHERE DupeCount > 1 
+0

Einverstanden, @ Forty3. Es klappt. Danke, dass Sie die Antwort geschrieben haben. Ich habe gefunden, dass 'ORDER BY [Datum], [ItemID], [ClientName], [Metric1], [Metric2]' nach 'WHERE DupeCount> 1' hinzugefügt wurden, um mir die Überprüfung von Dupes zu erleichtern. :) – user1330974

Verwandte Themen