Inserisci date mancanti da una query


9

Come posso inserire le date mancanti da una query che ho creato. Il risultato di seguito:

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

Voglio che il risultato abbia date mancanti con valore 0 come mostrato di seguito:

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

Si noti che ho accesso in sola lettura al server.


stai usando qualche query per recuperare il risultato? o hai definito un intervallo di date. puoi aggiungere la tua query o tabella
vijayp

1
Usa una tabella del calendario, selezionala e poi unisciti alle tue frequenze per data social.technet.microsoft.com/wiki/contents/articles/…
Mark Sinkinson

Sto usando la query per recuperare il risultato dalla tabella principale.
Arvin,

Se si dispone dell'accesso in sola lettura , non è necessario inserire o aggiornare il database. Chiedi invece al tuo team DBA di aiutarti.
Kin Shah,

1
@Kin Penso che la domanda significhi che vogliono inserire righe nel set di risultati, piuttosto che inserire righe in una tabella di database reale.
Mark Sinkinson,

Risposte:


12

Ecco un esempio usando una tabella del calendario (che dovresti davvero avere). Questo esempio popola solo il 2014 ma puoi riempirlo con tutti gli anni che vuoi ...

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;

Ora la query è semplice:

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);

Esempio di SQLfiddle

Se non riesci a creare una tabella del calendario (e non hai nemmeno una tabella dei numeri a portata di mano), puoi semplicemente metterla in linea:

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);

Esempio di SQLfiddle

Per ulteriori informazioni sulla generazione di set (di date, numeri, ecc.) Vedere questa serie:


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

VIOLINO

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

L'approccio CTE ricorsivo diventa esponenzialmente più costoso man mano che l'intervallo di date si amplia. Esistono modi più efficienti per derivare set per questo scopo.
Aaron Bertrand

@AaronBertrand La gamma è piuttosto piccola qui, ma qualsiasi collegamento ad alternative? Per la mia curiosità.
Mihai,

1
Sì, qui , sembra essere una piccola gamma. Il problema è che le persone imparano questo approccio e poi lo applicano in scale molto più grandi dove diventa un problema. Perché usare un approccio lento solo perché è "ok" in questo caso? Vedi la mia risposta
Aaron Bertrand
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.