Insérer des dates manquantes à partir d'une requête


9

Comment puis-je insérer des dates manquantes dans une requête que j'ai créée. Le résultat ci-dessous:

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

Je veux que le résultat ait des dates manquantes avec une valeur 0 comme indiqué ci-dessous:

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

Veuillez noter que je n'ai accès qu'en lecture seule au serveur.


utilisez-vous une requête pour récupérer le résultat? ou avez-vous défini une plage de dates. pouvez-vous ajouter votre requête ou table
vijayp

1
Utilisez un tableau de calendrier, sélectionnez-le et rejoignez vos fréquences par date social.technet.microsoft.com/wiki/contents/articles/…
Mark Sinkinson

J'utilise une requête pour récupérer le résultat de la table principale.
Arvin

Si vous disposez d' un accès en lecture seule , vous n'êtes pas censé insérer ou mettre à jour la base de données. Demandez plutôt à votre équipe DBA de vous aider.
Kin Shah

1
@Kin Je pense que la question signifie qu'ils veulent insérer des lignes dans le jeu de résultats, plutôt que d'insérer des lignes dans une table de base de données réelle.
Mark Sinkinson

Réponses:


12

Voici un exemple utilisant une table de calendrier (que vous devriez vraiment avoir). Cet exemple ne remplit que 2014, mais vous pouvez le remplir avec autant d'années que vous le souhaitez ...

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;

Maintenant, la requête est simple:

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

Exemple SQLfiddle

Si vous ne pouvez pas créer une table de calendrier (et que vous n'avez pas non plus de table de nombres à portée de main), vous pouvez simplement la mettre en ligne:

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

Exemple SQLfiddle

Pour en savoir plus sur les groupes électrogènes (de dates, nombres, etc.), consultez cette 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

VIOLON

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'approche CTE récursive devient exponentiellement plus chère à mesure que la plage de dates s'élargit. Il existe des moyens plus efficaces de dériver des ensembles à cet effet.
Aaron Bertrand

@AaronBertrand La gamme est assez petite ici, mais tout lien vers des alternatives? Pour ma curiosité.
Mihai

1
Oui, ici , il se trouve que c'est une petite plage. Le problème est que les gens apprennent cette approche et l'appliquent ensuite à des échelles beaucoup plus grandes où cela devient un problème. Pourquoi utiliser une approche lente juste parce que c'est "ok" dans ce cas? Voir ma réponse.
Aaron Bertrand
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.