sql - How does one summarise data grouped by a column and date, accounting for dates with missing data -
i'm creating report i'd number of events grouped day , tag, filtered specific tags (like '%sample%') , specific period (e.g. past week).
i'm using sql server 2008.
there days when no events specific tag occurred. problem have how generate rows days no rows exist , give them value of zero. similar following:
tag date count =================== =============== ==================== sample 2013-07-07 0 sample 2013-07-08 0 sample 2013-07-09 0 sample 2013-07-10 0 sample 2013-07-11 0 sample 2013-07-12 1 sample 2013-07-13 0 xxx sample xxx 2013-07-07 0 xxx sample xxx 2013-07-08 0 xxx sample xxx 2013-07-09 0 xxx sample xxx 2013-07-10 3 xxx sample xxx 2013-07-11 0 xxx sample xxx 2013-07-12 0 xxx sample xxx 2013-07-13 0 yyy sample yyy 2013-07-07 0 yyy sample yyy 2013-07-08 0 yyy sample yyy 2013-07-09 0 yyy sample yyy 2013-07-10 1 yyy sample yyy 2013-07-11 0 yyy sample yyy 2013-07-12 0 yyy sample yyy 2013-07-13 0
the 0 days important in order render data in graphs, each "tag" own graph, time x-axis or count y-axis.
schema
the tags table follows:
create table tags ( [id] [int] identity(1,1) not null, [name] [nvarchar](64) not null, constraint [pk_tags] primary key clustered ( [id] asc ) on [primary] ) on [primary]
and events table follows:
create table [dbo].[events]( [id] [int] identity(1,1) not null, [message] [varchar](128) null, [tagid] [int] not null, [createdat] [datetime] null, constraint [pk_events] primary key clustered ( [id] asc ) on [primary] )
where tagid foreign key tags table.
sample data
the events table has following data
id message tagid createdat === =========== ======= ========================= 1 message 1 1 2013-07-10 18:46:04.967 2 message 2 2 2013-07-14 18:46:10.547 3 message 3 3 2013-07-12 18:46:15.190 4 message 4 4 2013-07-14 18:46:20.673 5 message 5 2 2013-07-14 18:46:28.133 8 message 6 1 2013-07-10 14:46:04.967 9 message 7 1 2013-07-10 12:46:04.967 10 message 6 2 2013-07-10 14:46:04.967
and tags table has following data:
id name === =========================== 3 sample 4 test1 5 test2 6 test3 1 xxx sample xxx 2 yyy sample yyy
what i've tried
so, joined table getting following:
select tags.name, convert(date, events.createdat) date,count(*) count events inner join tags on events.tagid = tags.id tags.name '%sample%' group tags.name, convert(date, events.createdat) order tags.name, convert(date, events.createdat)
which returned
name date count =================== =============== ================ sample 2013-07-12 1 xxx sample xxx 2013-07-10 3 yyy sample yyy 2013-07-10 1 yyy sample yyy 2013-07-14 2
i searched ways generated rows days there no data. found entry sql server: how select days in date range if no data exists days unable work.
to verify got right days, ran following query:
with datetable ( select convert(date, dateadd(week, -1, getdate())) [date] union select dateadd(dd, 1, [date]) datetable dateadd(dd, 1, [date]) < convert(date, getdate()) ) select datetable.date datetable
which returned:
2013-07-07 2013-07-08 2013-07-09 2013-07-10 2013-07-11 2013-07-12 2013-07-13
my first attempt work without specifying like '%sample%'
in clause.
with datetable ( select convert(date, dateadd(week, -1, getdate())) [date] union select dateadd(dd, 1, [date]) datetable dateadd(dd, 1, [date]) < convert(date, getdate()) ) select tags.name, dt.[date] date, count(events.id) count events inner join tags on tags.id = events.tagid right join [datetable] dt on dt.[date] = convert(date, events.[createdat]) tagid not null group tags.name, dt.[date]
i following result:
name date count =================== =============== ================ xxx sample xxx 2013-07-10 3 yyy sample yyy 2013-07-10 1 sample 2013-07-12 1
i have tried other things, changing right join
left join
, i'm unable desired result.
with datetable ( select convert(date, dateadd(week, -1, getdate())) [date] union select dateadd(dd, 1, [date]) datetable dateadd(dd, 1, [date]) < convert(date, getdate()) ) select tags.name, dt.date date,count(events.id) count datetable dt cross join tags tags left join events on dt.[date] = convert(date, events.[createdat]) , tags.id = events.tagid tags.name '%sample%' group tags.name, date order tags.name, date;
Comments
Post a Comment