2016-04-25 11 views
0

Ich habe eine Tabelle wie folgt:SQL mit doppelten Datensätzen nach dem Datum Unterschied zu tun

id  start_date  end_date 
01  2012-03-15 2012-04-02 
01  2012-04-05 2012-05-12 
01  2012-04-12 2012-05-21 
02  2012-03-05 2012-06-13 
03  2012-03-09 2012-03-19 
03  2012-05-15 2012-08-01 

Die Definition von doppelten Datensätzen hier ist jede Vielzahl von Reihen mit derselben ID und deren start_dates sind innerhalb von 31 Tagen voneinander . In dem obigen Beispiel, Reihe 2, 3 sind Duplikate von 1 und Zeile 6 wird kein Duplikat Zeile 5. Ich möchte die Duplikate entfernen zu bekommen:

id  start_date  end_date 
01  2012-03-15 2012-04-02 
02  2012-03-05 2012-06-13 
03  2012-03-09 2012-03-19 
03  2012-05-15 2012-08-01 

Ich frage mich, ob diese Art der Filterung ist besser in Python getan, nachdem die Daten mit Duplikaten gesammelt wurden oder wenn es eine einfache Möglichkeit gibt, es in SQL zu tun.

+0

Können Sie doppelte Startdaten für jede ID haben? (Und wenn ja, wie entscheiden Sie, welches das Duplikat ist?) – ZLK

+0

Nein. Es gibt keine Duplikate für dasselbe Startdatum und dieselbe ID. – breezymri

+0

Sie könnten es in Python mit minimalem Code erzwingen, iterieren über alle Zeilen, wenn das Datum <31 Tage in der vorherigen Zeile und die ID ist die gleiche Zeile löschen. Das ist einfach zu programmieren. Dann hängt es von der Leistung ab, die Iteration wird in Python wahrscheinlich langsam sein. – flyingmeatball

Antwort

0

Ich denke, dass Sie eine Art von Rekursion verwenden müssen, unabhängig davon, welche Sprache Sie wählen. Hier ist ein Beispiel dafür, wie man es in SQL tun könnte:

DECLARE @ TABLE (ID INT, start_date DATE, end_date DATE); 
INSERT @ VALUES (1,'2012-03-15','2012-04-02') 
, (1,'2012-04-05','2012-05-12') 
, (1, '2012-04-12', '2012-05-21') 
, (2, '2012-03-05', '2012-06-13') 
, (3, '2012-03-09', '2012-03-19') 
, (3, '2012-04-03', '2012-05-02') 
, (3, '2012-05-01', '2012-08-01') 
, (3, '2012-05-16', '2012-08-02') 
, (3, '2012-06-08', '2012-09-09'); 

WITH T AS (
    SELECT id, start_date, end_date, RN 
    FROM (
     SELECT id, start_date, end_date, ROW_NUMBER() OVER (PARTITION BY id ORDER BY start_date) RN 
     FROM @) S 
    WHERE RN = 1 

    UNION ALL 

    SELECT S.id 
     , CASE WHEN DATEDIFF(dd, T.start_date, S.start_date) <= 31 THEN T.start_date ELSE S.start_date END 
     , CASE WHEN DATEDIFF(dd, T.start_date, S.start_date) <= 31 THEN T.end_date ELSE S.end_date END 
     , S.RN 
    FROM (
     SELECT id, start_date, end_date, ROW_NUMBER() OVER (PARTITION BY id ORDER BY start_date) RN 
     FROM @) S 
    JOIN T ON T.id = S.id 
    WHERE S.RN = T.RN+1 
    ) 
SELECT id, start_date, end_date 
FROM T 
GROUP BY id, start_date, end_date; 

die gut arbeitet für ein nicht-large-at-all Probengröße, aber wenn man auf einer Menge von Zeilen sucht, ist es wahrscheinlich nicht die effizienteste Art, dies zu tun.

+0

Ich denke, ich werde das in Python tun. – breezymri

Verwandte Themen