Inserir datas ausentes de uma consulta


9

Como posso inserir datas ausentes de uma consulta que eu criei. O resultado abaixo:

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

Quero que o resultado tenha datas ausentes com o valor 0, como mostrado abaixo:

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

Observe que eu tenho acesso somente de leitura ao servidor.


você está usando alguma consulta para buscar o resultado? ou você tem um período definido. você pode adicionar sua consulta ou tabela
vijayp

11
Use uma tabela de calendário, selecione com isso e, em seguida, juntar-se aos seus frequências por data social.technet.microsoft.com/wiki/contents/articles/...
Mark Sinkinson

Estou usando a consulta para buscar o resultado da tabela principal.
Arvin

Se você tiver acesso somente leitura , não deverá inserir ou atualizar o banco de dados. Em vez disso, peça à sua equipe do DBA para ajudá-lo.
Kin Shah

11
@ Kin Acho que a pergunta significa que eles querem inserir linhas no conjunto de resultados, em vez de inserir linhas em uma tabela de banco de dados real.
Mark Sinkinson

Respostas:


12

Aqui está um exemplo usando uma tabela de calendário (que você realmente deveria ter). Este exemplo apenas preenche 2014, mas você pode preenchê-lo com quantos anos quiser ...

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;

Agora a consulta é simples:

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

Exemplo de SQLfiddle

Se você não pode criar uma tabela de calendário (e também não possui uma tabela de números), basta colocá-la em linha:

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

Exemplo de SQLfiddle

Para saber mais sobre a geração de conjuntos (de datas, números etc.), consulte esta série:


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

FIDDLE

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

A abordagem CTE recursiva fica exponencialmente mais cara à medida que o período aumenta. Existem maneiras mais eficientes de derivar conjuntos para esse fim.
Aaron Bertrand

@AaronBertrand O alcance é bem pequeno aqui, mas qualquer link para alternativas? Para minha curiosidade.
Mihai

11
Sim, aqui , acontece que é um pequeno intervalo. O problema é que as pessoas aprendem essa abordagem e a aplicam em escalas muito maiores, onde ela se torna um problema. Por que usar uma abordagem lenta apenas porque está "ok" neste caso? Veja minha resposta.
Aaron Bertrand
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.