2016-03-21 10 views
0

Ich habe eine SQL Server-Tabelle mit einem Datumsfeld, den Namen einer Person und eine eindeutige Kennung. Die Daten sind alle innerhalb von 2015 und sind bis zum Ende des Wochenendes. Zum Beispiel 2015-12-05, dann 2015-12-12. Ich muss eine Liste der eindeutigen Identifikatoren finden, die eine Datenlücke von mindestens 3 Monaten aufweisen.Suchen Lücken zwischen Monaten

Also, wenn eindeutige Kennung A, hat Einträge von 2015-12-12 und 2015-07-25, dann würde ich es in meinen Ergebnissen sehen wollen. Wenn die Einträge konsistenter sind, sagen wir eine Woche pro Monat, möchte ich das nicht in meinen Ergebnissen sehen. Ich muss alle eindeutigen Kennzeichnungen mit einer 3-Monatslücke überall in 2015 zeigen.

Ich bin nicht wirklich sicher, wo ich anfangen soll. Irgendwelche Ideen?

+0

Hier ist ein großartiger Ort, um zu beginnen. http://spaghettidba.com/2015/04/24/how-to-post-a-t-sql-question-on-a-public-forum/ –

+1

WHERE NICHT EXISTEN() wäre eine gute Idee. –

+0

Ist die eindeutige Kennung pro Zeile oder pro Person? Bitte geben Sie die Tabellenstruktur an (die Anweisung 'CREATE' für die Tabelle reicht aus). – Ruslan

Antwort

0

Ich landete die Monate mit der Rank-Funktion und Rang, der für jede Kennung auf dem Tisch vorhanden ist. Zum Beispiel

select identifier,month,RANK() OVER (PARTITION BY identifier ORDER BY month) rnk 

table1

ich dann alle Daten aus dieser Abfrage in eine temporäre Tabelle hochgeladen. Dann habe ich die Lead- und Lag-Funktionen verwendet, um den Monat der vorherigen Zeilen und den Monat der nächsten Zeile zu ziehen. Stellen Sie sicher, dass Sie alle Daten richtig sortiert haben. Ich habe das auch in eine temporäre Tabelle eingefügt.

Dann habe ich diese temporäre Tabelle abgefragt, um anzuzeigen, wo eine Lücke 3 Monate oder länger war.

select identifier, PreviousMonth,NextMonth,Month-PreviousMonth as Month_Gap from #table2 where month-PreviousMonth >0 and month-PreviousMonth >=3 and rnk>1 

Ich hoffe, das hilft und macht Sinn. So endete meine endgültige Ausgabe in etwa wie folgt.

table2

0

Was denken Sie darüber nach:

ANSI 89

SELECT t1.* from 
your_table as t1,your_table as t2 
where DATEDIFF(month,t1.your_date_field,t2.your_date_field) >= 3 and 
t1.your_unique_id=t2.your_unique_id and 
not exists(
    select 1 
    from your_table as t3 
    where t3.your_unique_id = t1.your_unique_id and 
    DATEDIFF(month,t1.your_date_field,t3.your_date_field) < 3 
) 

ANSI 92

SELECT t1.* from 
your_table as t1 
    inner join your_table as t2 on t1.your_unique_id=t2.your_unique_id 
where DATEDIFF(month,t1.your_date_field,t2.your_date_field) >= 3 and 
not exists(
    select 1 
    from your_table as t3 
    where t3.your_unique_id = t1.your_unique_id and 
    DATEDIFF(month,t1.your_date_field,t3.your_date_field) < 3 
) 

Sie mehr Erklärung benötigen?

+0

Sind t1 und t2 ein Join auf der gleichen Tabelle? –

+0

Da beide "your_table" genannt werden, dann "yes" .... –

+0

Das funktioniert nicht wirklich. Wenn es jeden Monat einen Eintrag für 6 Monate gab, würde dies immer noch einige Ergebnisse liefern. Es verwendet auch die alten ANSI-89-Joins. –

0

würde ich vorschlagen, wie diese zu verwenden GILT:

SELECT DISTINCT t1.id FROM <table> t1 
    CROSS APPLY (SELECT TOP 1 t.date FROM <table> t 
     WHERE t.id = t1.id AND t.date < t1.date ORDER BY t.date DESC) t2 
WHERE DATEDIFF(month, t1.date, t2.date) >= 3 
Verwandte Themen