2016-07-12 5 views
1

Ich habe Probleme beim Aufteilen eines Datensatzes in mehrere andere Datensätze, so dass ich die Min-Werte aus ihnen bekommen kann. Grundeinstellung hierfür: Schlüssel kann gleichzeitig in verschiedenen Ländern verwendet werden (Länder-IDs sind in Spalte a). Ein Schlüssel (Spalte b im Bild) kann nach einer bestimmten Zeit wieder verwendet werden, in diesem Fall 120 Tage. Ein Schlüssel kann ungefähr 10 Ereignisse zusammen mit Daten haben.Aufteilen von Daten in Windows und Abrufen von Mindestwert aus diesem Fenster in Tsql

Picture with sample data (I have colored the theoretical boundaries for each of the periods or whatever you call them)

Das, was ich versucht zu tun ist, ein und b Spalten das erste Datum des ganzen Satzes und Aufteilung über Aufnahme und Verwendung von datediff() die Anzahl der Tage zwischen dem min Datum der bekommen ganze Reihe und jedes einzelne Ereignis. und dann nachher die Nummer verwenden, die von Datiff/120 zurückgegeben wurde, um sie zu gruppieren. Die Sache, die ich wirklich machen wollte, ist, das Min-Datum jedes Satzes (nicht den ganzen Satz) zu nehmen und darauf basierend zu berechnen. Ich hoffe wirklich, dass ich Ihnen genug gute Helfer erklärt habe, um zu verstehen, wonach ich suche. Jetzt, wo ich denke ... Ich mache mir Sorgen, dass, selbst wenn ich das Mindestdatum eines einzelnen Satzes bekommen und es dann durch 120 teilen würde, würde ich falsche Ergebnisse bekommen. Irgendwelche Vorschläge geschätzt!

Gebraucht ich etwas wie folgt aus: DATEDIFF(d,min(dates) OVER (PARTITION BY a, b), dates)/120

Visual explanation of what I need to achieve and how.

   sample data         desired outcome 
| CountryId | Key  |  date  | | CountryId |  Key |  date  | 
|-------------|-------------|--------------| |-------------|-------------|--------------| 
| 2   | 093123124 | 2015-04-16 | | 2   | 093123124 | 2015-04-16 | 
| 2   | 093123124 | 2015-04-16 | | 2   | 093123124 | 2015-11-24 | 
| 2   | 093123124 | 2015-04-17 | | 2   | 093123124 | 2016-04-17 | 
| 2   | 093123124 | 2015-04-17 | 
| 2   | 093123124 | 2015-11-24 | 
| 2   | 093123124 | 2015-11-24 | 
| 2   | 093123124 | 2015-11-25 | 
| 2   | 093123124 | 2015-11-25 | 
| 2   | 093123124 | 2015-11-25 | 
| 2   | 093123124 | 2016-04-17 | 
| 2   | 093123124 | 2016-04-18 | 
| 2   | 093123124 | 2016-04-20 | 
| 2   | 093123124 | 2016-04-21 | 
| 2   | 093123124 | 2016-04-22 | 
+2

Ist besser, wenn Sie Ihre Daten als Text veröffentlichen, können wir nicht Paste aus Bild kopieren. Zeigen Sie uns das Datenbankschema, die Beispieldaten und die erwartete Ausgabe. Bitte lesen Sie [** How-to-Ask **] (http://stackoverflow.com/help/how-to-ask) \t \t Und hier ist ein großartiger Ort, um [** START **] (http : //spaghettidba.com/2015/04/24/how-to-post-at-sql-question-on-a-public-forum/) um zu erfahren, wie Sie die Qualität Ihrer Fragen verbessern und bessere Antworten erhalten. –

+0

Daten als Text hinzugefügt, so dass es einfacher zu kopieren ist, sowie das erwartete Ergebnis. Danke für die Tipps. –

+0

Zuerst sieht es aus wie ein 'DISTINCT' ... Aber ich verstehe nicht die Logik für Ihre Wunschausgabe. Wohin geh '11-25'? Anstelle von 'a, b, c' benutzen Sie auch die Variablennamen –

Antwort

0

Diese für CTE wie ein Fall zu sein scheinen. Der folgende Code findet, dass jede Gruppe rekursiv 120 Tage für jede Rekursion hinzufügt.

SET DATEFORMAT YMD 
DECLARE @SampleData TABLE( A INT, 
          B NVARCHAR(25), 
          C DATETIME) 


INSERT INTO @SampleData(A, B, C) 
VALUES (2,'093123124', CONVERT(DATETIME, '2015-04-16')), 
     (2,'093123124', CONVERT(DATETIME, '2015-04-16')), 
     (2,'093123124', CONVERT(DATETIME, '2015-04-17')), 
     (2,'093123124', CONVERT(DATETIME, '2015-04-17')), 
     (2,'093123124', CONVERT(DATETIME, '2015-11-24')), 
     (2,'093123124', CONVERT(DATETIME, '2015-11-24')), 
     (2,'093123124', CONVERT(DATETIME, '2015-11-25')), 
     (2,'093123124', CONVERT(DATETIME, '2015-11-25')), 
     (2,'093123124', CONVERT(DATETIME, '2015-11-25')), 
     (2,'093123124', CONVERT(DATETIME, '2016-04-17')), 
     (2,'093123124', CONVERT(DATETIME, '2016-04-18')), 
     (2,'093123124', CONVERT(DATETIME, '2016-04-20')), 
     (2,'093123124', CONVERT(DATETIME, '2016-04-21')), 
     -- (2,'093123124', CONVERT(DATETIME, '2016-03-24')), 
     (2,'093123124', CONVERT(DATETIME, '2016-04-22')); 

WITH lvl1 
AS 
(
    SELECT A, 
      B, 
      C = MIN(C) 
    FROM @SampleData 
    GROUP BY A, 
       B 
), 
lvlOthers 
AS 
(
    SELECT A, 
      B, 
      C 
    FROM lvl1 
    UNION ALL 
    SELECT S.A, 
      S.B, 
      C = MIN(S.C) OVER(PARTITION BY S.A, S.B) 
    FROM lvlOthers 
    INNER JOIN @SampleData AS S ON lvlOthers.A = S.A 
           AND lvlOthers.B = S.B 
           AND S.C > DATEADD(DAY, 120, lvlOthers.C) 
) 

SELECT DISTINCT A, B, C 
FROM lvlOthers 
OPTION (MAXRECURSION 100) 

Beware, dass dieser Code nicht für die Leistung abgestimmt ist. In der Tat wird es bei großen Datenmengen schlecht funktionieren.

Außerdem sollte die maximale Rekursion erhöht werden, wenn der Datumsbereich ~ 32 Jahre überschreitet.

+0

Super! Das war genau das, was ich brauchte, um auf dem richtigen Weg zu sein. –

Verwandte Themen