Fehlende Daten aus einer Abfrage einfügen

9

Wie kann ich fehlende Daten aus einer von mir erstellten Abfrage einfügen? Das Ergebnis unten:

Date          Frequency
2014-05-18    5
2014-05-20    7
2014-05-25    7
2014-05-27    6

Ich möchte, dass das Ergebnis fehlende Daten mit dem Wert 0 enthält, wie unten gezeigt:

Date          Frequency
2014-05-18    5
2014-05-19    0
2014-05-20    7
2014-05-21    0
2014-05-22    0
2014-05-23    0
2014-05-24    0
2014-05-25    7
2014-05-26    0
2014-05-27    6

Bitte beachten Sie, dass ich nur Lesezugriff auf den Server habe.

Arvin
quelle
Verwenden Sie eine Abfrage, um das Ergebnis abzurufen? oder haben Sie einen Datumsbereich definiert. können Sie Ihre Abfrage oder Tabelle hinzufügen
Vijayp
1
Verwenden Sie eine Kalendertabelle, wählen Sie diese aus und schließen Sie sich Ihren Frequenzen nach Datum an. Social.technet.microsoft.com/wiki/contents/articles/…
Mark Sinkinson
Ich verwende die Abfrage, um das Ergebnis aus der Haupttabelle abzurufen.
Arvin
Wenn Sie nur Lesezugriff haben, dürfen Sie die Datenbank nicht einfügen oder aktualisieren. Bitten Sie stattdessen Ihr DBA-Team, Ihnen zu helfen.
Kin Shah
1
@Kin Ich denke, die Frage bedeutet, dass sie Zeilen in die Ergebnismenge einfügen möchten, anstatt Zeilen in eine tatsächliche Datenbanktabelle einzufügen.
Mark Sinkinson

Antworten:

12

Hier ist ein Beispiel mit einer Kalendertabelle (die Sie wirklich haben sollten). Dieses Beispiel füllt nur 2014, aber Sie können es mit so vielen Jahren füllen, wie Sie möchten ...

CREATE TABLE dbo.Calendar(d DATE PRIMARY KEY);

INSERT dbo.Calendar(d) SELECT TOP (365)
 DATEADD(DAY, ROW_NUMBER() OVER (ORDER BY number)-1, '20140101')
 FROM [master].dbo.spt_values
 WHERE [type] = N'P' ORDER BY number;

Jetzt ist die Abfrage einfach:

DECLARE @s DATE = '20140518', @e DATE = '20140527';

SELECT c.d, Frequency = COALESCE(s.Frequency,0)
  FROM dbo.Calendar AS c
  LEFT OUTER JOIN dbo.splunge AS s
  ON c.d = s.[date]
  WHERE c.d >= @s
    AND c.d < DATEADD(DAY, 1, @e);

SQLfiddle-Beispiel

Wenn Sie keine Kalendertabelle erstellen können (und auch keine Zahlentabelle zur Hand haben), können Sie sie einfach inline setzen:

DECLARE @s DATE = '20140518', @e DATE = '20140527';

SELECT c.d, Frequency = COALESCE(s.Frequency,0)
  FROM 
(
   SELECT TOP (DATEDIFF(DAY, @s, @e)+1)
 DATEADD(DAY, ROW_NUMBER() OVER (ORDER BY number)-1, @s)
 FROM [master].dbo.spt_values
 WHERE [type] = N'P' ORDER BY number
) AS c(d)
  LEFT OUTER JOIN dbo.splunge2 AS s
  ON c.d = s.[date]
  WHERE c.d >= @s
    AND c.d < DATEADD(DAY, 1, @e);

SQLfiddle-Beispiel

Weitere Informationen zu Generierungssätzen (von Datumsangaben, Zahlen usw.) finden Sie in dieser Reihe:

Aaron Bertrand
quelle
0
DECLARE @t TABLE(Dt Date,Frequency int)
INSERT INTO @t VALUES
('2014-05-18',5),('2014-05-20',7),('2014-05-25',7),('2014-05-27',6)



DECLARE @startDate DATE, @endDate DATE
SELECT @startDate = '2014-05-18', @endDate = '2014-05-27' --yyyy-mm-dd
;WITH Calender AS (
    SELECT @startDate AS CalanderDate
    UNION ALL
    SELECT DATEADD(day,1,CalanderDate) FROM Calender
    WHERE DATEADD(day,1,CalanderDate) <= @endDate
)
INSERT INTO @t SELECT
    Dt = CalanderDate,Frequency = 0

FROM Calender c
LEFT JOIN @t t 
ON t.Dt = c.CalanderDate
WHERE t.dt IS NULL
option (maxrecursion 0)

SELECT * FROM @t ORDER BY dt

GEIGE

2014-05-18  5
2014-05-19  0
2014-05-20  7
2014-05-21  0
2014-05-22  0
2014-05-23  0
2014-05-24  0
2014-05-25  7
2014-05-26  0
2014-05-27  6
Mihai
quelle
Der rekursive CTE-Ansatz wird mit zunehmendem Datumsbereich exponentiell teurer. Es gibt effizientere Möglichkeiten, Mengen für diesen Zweck abzuleiten.
Aaron Bertrand
@ AaronBertrand Das Sortiment ist hier ziemlich klein, aber irgendein Link zu Alternativen? Für meine Neugier.
Mihai
1
Ja, hier ist es zufällig eine kleine Reichweite. Das Problem ist, dass die Leute diesen Ansatz lernen und ihn dann in viel größeren Maßstäben anwenden, wo er zum Problem wird. Warum einen langsamen Ansatz verwenden, nur weil er in diesem Fall "in Ordnung" ist? Siehe meine Antwort.
Aaron Bertrand