ryw
ryw

Reputation: 9655

sql missing rows when grouped by DAY, MONTH, YEAR

If I select from a table group by the month, day, year, it only returns rows with records and leaves out combinations without any records, making it appear at a glance that every day or month has activity, you have to look at the date column actively for gaps. How can I get a row for every day/month/year, even when no data is present, in T-SQL?

Upvotes: 4

Views: 4417

Answers (5)

ryw
ryw

Reputation: 9655

My developer got back to me with this code, underscores converted to dashes because StackOverflow was mangling underscores -- no numbers table required. Our example is complicated a bit by a join to another table, but maybe the code example will help someone someday.

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 

Upvotes: 1

6eorge Jetson
6eorge Jetson

Reputation: 2235

The task calls for a complete set of dates to be left-joined onto your data, such as


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]

where the table-valued function tvfUtilGenerateIntegerList is defined as


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

Upvotes: 0

Joel Coehoorn
Joel Coehoorn

Reputation: 416059

Building on what SQLMenace said, you can use a CROSS JOIN to quickly populate the table or efficiently create it in memory.
http://www.sitepoint.com/forums/showthread.php?t=562806

Upvotes: 0

Tom Mayfield
Tom Mayfield

Reputation: 6276

Look into using a numbers table. While it can be hackish, it's the best method I've come by to quickly query missing data, or show all dates, or anything where you want to examine values within a range, regardless of whether all values in that range are used.

Upvotes: 0

SQLMenace
SQLMenace

Reputation: 135111

Create a calendar table and outer join on that table

Upvotes: 5

Related Questions