lignes manquantes SQL lorsqu'elles sont regroupées par JOUR, MOIS, ANNÉE
Question
Si je sélectionne parmi un groupe de table d'ici le mois, le jour, l'année, il ne renvoie que des rangées avec des records et laisse de côté les combinaisons sans aucun enregistrement, faisant apparaître en un coup d'œil que chaque jour ou chaque mois a une activité, vous devez regarder la date colonne activement pour les lacunes.Comment puis-je obtenir une ligne pour chaque jour/mois/année, même en l'absence de données, dans T-SQL ?
La solution 2
Mon développeur m'est revenu avec ce code, les traits de soulignement convertis en tirets parce que StackOverflow mutilait les traits de soulignement - aucune table de nombres n'était requise.Notre exemple est un peu compliqué par une jointure à une autre table, mais peut-être que l'exemple de code aidera quelqu'un un jour.
declare @career-fair-id int
select @career-fair-id = 125
create table #data ([date] datetime null, [cumulative] int null)
declare @event-date datetime, @current-process-date datetime, @day-count int
select @event-date = (select careerfairdate from tbl-career-fair where careerfairid = @career-fair-id)
select @current-process-date = dateadd(day, -90, @event-date)
while @event-date <> @current-process-date
begin
select @current-process-date = dateadd(day, 1, @current-process-date)
select @day-count = (select count(*) from tbl-career-fair-junction where attendanceregister <= @current-process-date and careerfairid = @career-fair-id)
if @current-process-date <= getdate()
insert into #data ([date], [cumulative]) values(@current-process-date, @day-count)
end
select * from #data
drop table #data
Autres conseils
Créez une table de calendrier et une jointure externe sur cette table
Pensez à utiliser un tableau des nombres.Bien que cela puisse être hackish, c'est la meilleure méthode que j'ai utilisée pour interroger rapidement les données manquantes, ou afficher toutes les dates, ou tout ce que vous souhaitez examiner les valeurs dans une plage, que toutes les valeurs de cette plage soient utilisées ou non.
En vous basant sur ce que SQLMenace a dit, vous pouvez utiliser un CROSS JOIN pour remplir rapidement la table ou la créer efficacement en mémoire.
http://www.sitepoint.com/forums/showthread.php?t=562806
La tâche nécessite qu'un ensemble complet de dates soit joint à gauche sur vos données, telles que
DECLARE @StartInt int
DECLARE @Increment int
DECLARE @Iterations int
SET @StartInt = 0
SET @Increment = 1
SET @Iterations = 365
SELECT
tCompleteDateSet.[Date]
,AggregatedMeasure = SUM(ISNULL(t.Data, 0))
FROM
(
SELECT
[Date] = dateadd(dd,GeneratedInt, @StartDate)
FROM
[dbo].[tvfUtilGenerateIntegerList] (
@StartInt,
,@Increment,
,@Iterations
)
) tCompleteDateSet
LEFT JOIN tblData t
ON (t.[Date] = tCompleteDateSet.[Date])
GROUP BY
tCompleteDateSet.[Date]
où la fonction table tvfUtilGenerateIntegerList est définie comme
-- Example Inputs
-- DECLARE @StartInt int
-- DECLARE @Increment int
-- DECLARE @Iterations int
-- SET @StartInt = 56200
-- SET @Increment = 1
-- SET @Iterations = 400
-- DECLARE @tblResults TABLE
-- (
-- IterationId int identity(1,1),
-- GeneratedInt int
-- )
-- =============================================
-- Author: 6eorge Jetson
-- Create date: 11/22/3333
-- Description: Generates and returns the desired list of integers as a table
-- =============================================
CREATE FUNCTION [dbo].[tvfUtilGenerateIntegerList]
(
@StartInt int,
@Increment int,
@Iterations int
)
RETURNS
@tblResults TABLE
(
IterationId int identity(1,1),
GeneratedInt int
)
AS
BEGIN
DECLARE @counter int
SET @counter= 0
WHILE (@counter < @Iterations)
BEGIN
INSERT @tblResults(GeneratedInt) VALUES(@StartInt + @counter*@Increment)
SET @counter = @counter + 1
END
RETURN
END
--Debug
--SELECT * FROM @tblResults