2016-12-20 3 views
-1

Ich habe eine Datentabelle und eine Kalender-Tabelle. Ich muss die Lücken füllen, um für jeden Tag eine Zeile zu haben. Ich brauche die Daten, die ausgefüllt werden müssen, sowie den vorherigen gültigen Wert für Sequenz und Aktion. NULL ist ein gültiger Aktionstyp. Ich bin nah dran, aber die NULLS haben mit meinen Ergebnissen geschraubt.SQL Ausfüllen von Daten und Daten

Ich benutze SQL Server 2014. Ihre Hilfe wird sehr geschätzt.

Daten:

ID | Sequence|    Date| Action| 
---|---------|--------------------|-------| 
A |  1 | 4/5/2016 12:09:23 | yield| 
A |  2 | 4/7/2016 12:25:16 | stop| 
A |  3 | 4/12/2016 11:25:42| NULL| 
A |  4 | 4/18/2016 11:25:42|  go| 
B |  1 | 2/17/2016 14:15:10| yield| 
B |  2 | 3/1/2016 7:56:37 | stop| 
B |  3 | 4/1/2016 9:24:46 |  go| 
B |  4 | 5/4/2016 12:25:16 | exit| 

Kalender:

DateKey |    Date| 
--------|--------------------| 
2838 | 4/6/2016 0:00:00 | 
2839 | 4/7/2016 0:00:00 | 
2840 | 4/8/2016 0:00:00 | 
2841 | 4/9/2016 0:00:00 | 
2842 | 4/10/2016 0:00:00 | 
2843 | 4/11/2016 0:00:00 | 
2844 | 4/12/2016 0:00:00 | 
2845 | 4/13/2016 0:00:00 | 
2846 | 4/14/2016 0:00:00 | 
2847 | 4/15/2016 0:00:00 | 
2848 | 4/16/2016 0:00:00 | 
2849 | 4/17/2016 0:00:00 | 
2850 | 4/18/2016 0:00:00 | 

Wunschergebnisse:

ID | Sequence|    Date| Action| 
----|---------|--------------------|----------| 
A |  1| 4/5/2016 12:09:23|  yield| 
A |  1| 4/6/2016 0:00:00|  yield| 
A |  2| 4/7/2016 12:25:16|  stop| 
A |  2| 4/8/2016 0:00:00|  stop| 
A |  2| 4/9/2016 0:00:00|  stop| 
A |  2| 4/10/2016 0:00:00|  stop| 
A |  2| 4/11/2016 0:00:00|  stop| 
A |  3| 4/12/2016 10:35:34|  NULL| 
A |  3| 4/13/2016 0:00:00|  NULL| 
A |  3| 4/14/2016 0:00:00|  NULL| 
A |  3| 4/15/2016 0:00:00|  NULL| 
A |  3| 4/16/2016 0:00:00|  NULL| 
A |  3| 4/17/2016 0:00:00|  NULL| 
A |  4| 4/18/2016 11:25:4|  go| 

TSQL Testtabellen aufstehen:

IF EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME =  'Data') 
    DROP TABLE Data; 

CREATE TABLE Data (ID varchar(20), SEQ INT, Date datetime, Action  varchar(20)); 

INSERT INTO data (ID, SEQ, Date, Action) VALUES 
('A', 1, '4/5/2016 12:09:23','yield'), 
('A', 2, '4/7/2016 12:25:16','stop'), 
('A', 3, '4/12/2016 11:25:42','NULL'), 
('A', 4, '4/18/2016 11:25:42','go') 



IF EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME =  'Calendar') 
    DROP TABLE Calendar; 

CREATE TABLE Calendar (DateKey int, Date datetime); 

INSERT INTO Calendar (DateKey, Date) VALUES 
('2838','4/6/2016 0:00:00'), 
('2839','4/7/2016 0:00:00'), 
('2840', '4/8/2016 0:00:00'), 
('2841', '4/9/2016 0:00:00'), 
('2842', '4/10/2016 0:00:00'), 
('2843', '4/11/2016 0:00:00'), 
('2844', '4/12/2016 0:00:00'), 
('2845', '4/13/2016 0:00:00'), 
('2846', '4/14/2016 0:00:00'), 
('2847', '4/15/2016 0:00:00'), 
('2848', '4/16/2016 0:00:00'), 
('2849', '4/17/2016 0:00:00'), 
('2850', '4/18/2016 0:00:00') 
+0

ich denke, es wäre viel einfacher, diese anstelle von SQL – CptMisery

+0

Leider mit dem Code zu tun mit den Tags glücklich klicken ... und ich würde code es, wenn ich in der Lage war ... – dk13

+0

Während ich nicht die Zeit habe, um die Abfrage für Sie zu schreiben, werde ich Sie in die richtige Richtung zeigen: Sie können etwas wie wählen * aus table1 t1 links join table2 tun t2 ON t1.dDate <= t2.dDate, das alle Zeilen aus Tabelle 1 mit allem zusammenfügt, was in Tabelle 2 übereinstimmt, wobei das Datum der Tabelle 2 größer oder gleich dem Datum in tb1 ist. In Ihrem Fall ist es komplizierter als das, aber eine solche Join-Bedingung ist, wo Sie beginnen möchten. –

Antwort

0

Was ist mit diesem SQL-Befehl?

SELECT A.[ID] 
     ,A.[SEQ] 
     ,ISNULL(A.[Date], B.[Date]) AS 'DATE' 
     ,A.[Action] 
FROM DATA A FULL JOIN CALENDAR B 
    ON cast(A.[Date] as DATE) = cast(B.[Date] as DATE) 
ORDER BY B.[date] ASC 

Das Ergebnis für die FULL JOIN Option:

ID | SEQ | DATE     | Action| 
----|-----|-------------------------|-------| 
A | 1 | 2016-04-05 12:09:23.000 |yield | 
NULL| NULL| 2016-04-06 00:00:00.000 |NULL | 
A | 2 | 2016-04-07 12:25:16.000 |stop | 
NULL| NULL| 2016-04-08 00:00:00.000 |NULL | 
NULL| NULL| 2016-04-09 00:00:00.000 |NULL | 
NULL| NULL| 2016-04-10 00:00:00.000 |NULL | 
NULL| NULL| 2016-04-11 00:00:00.000 |NULL | 
A | 3 | 2016-04-12 11:25:42.000 |NULL | 
NULL| NULL| 2016-04-13 00:00:00.000 |NULL | 
NULL| NULL| 2016-04-14 00:00:00.000 |NULL | 
NULL| NULL| 2016-04-15 00:00:00.000 |NULL | 
NULL| NULL| 2016-04-16 00:00:00.000 |NULL | 
NULL| NULL| 2016-04-17 00:00:00.000 |NULL | 
A | 4 | 2016-04-18 11:25:42.000 |go  | 
+0

Leider hat dies keine Zeile für jeden Tag – dk13

+0

Ich denke, was er tun wollte, ist die Gegenteil. FROM Kalender LEFT JOIN Daten anstelle von FROM Data LINKER JOIN Kalender (oder ändern Sie die LINKE JOIN für eine richtige JOIN, aber ich empfehle es nicht. Right JOINS sind dumm. Sie sind inverse LINKS 99.99% der Zeit, wie es würde in dieser Situation sein). Dies führt jedoch dazu, dass Tage aus dem Kalender nicht mit Tagen aus Daten mit NULL-Werten übereinstimmen. Es wird nicht die vorherigen Werte erhalten. Das ist der einfache Teil. Das Abrufen der vorherigen Werte für leere Tage ist der schwierigere Teil. Überprüfen Sie meinen Kommentar in Ihrem ersten Post für einen Blick auf die Lösung. –

+0

Ich habe tatsächlich die Daten zu füllen, aber wie Sie erwähnt haben, war der schwierige Teil, die vorherigen Werte zu bekommen. Die meisten Lösungen, die ich gesehen habe, verwenden eine Variation von "Top 1"/Reihenfolge, in Verbindung mit "wo Aktion nicht null ist" (das ist, wo es mich hat). – dk13