Is this fix for date-splitting 'bug' safe?
I have created a report that gets week-ending figures for a given account number. I used the datepart
function to group by week, which was fine, but a 'bug' (quoted because I'm not sure if it's a bug or correct behavour, but I didn't want the behavour) would occur at the end of the year. The grouping would split the last week in two, and show it as two rows (both with the same week end date, but one was week 53, and the other week 1) So I modified the group by clause accordingly...
group by
(case when datepart(wk,dbdate) = 53 then (year(dbdate) + 1) else year(dbdate) end)
,(case when datepart(wk,dbdate) = 53 then 1 else datepart(wk,dbdate) end)
It seems to work. And I tested it out with a few examples. But I just want to be sure that a) it will work in all conditions and b) is there a better way?
If it helps, here is the entire query...
开发者_如何学运维set datefirst 1
select
convert(varchar,min(DATEADD(dd, 7-(DATEPART(dw, dbdate)), dbdate)),106) [Week<br />Ending],
'$' + convert(VARCHAR,sum(handle),1) as Handle,
'$' + convert(varchar,sum(case when pool_type in ('WN','PL','SH','WP','WS','PS','WPS') then handle else 0 end),1) as WPS,
'$' + convert(varchar,sum(case when pool_type not in ('WN','PL','SH','WP','WS','PS','WPS') then handle else 0 end),1) as Exotics
from amtoteaccountactivity
where accountnumber ='$account'
and (_date >='$datestart' and _date <= '$dateend')
and pool_type not in ('TT2','TS2','BQ2','SS2') and transaction_type ='Bet'
group by
(case when datepart(wk,dbdate) = 53 then (year(dbdate) + 1) else year(dbdate) end)
,(case when datepart(wk,dbdate) = 53 then 1 else datepart(wk,dbdate) end)
order by min(DATEADD(dd, 7-(DATEPART(dw, dbdate)), dbdate))
Edit: what this essentially does is combine week 53's results with week 1 of the following year's results, thus recombining the split week. Because the SQL engine is counting the last week of the first year as 'week 1' of the following year AND week 53 of the preceding year.
we use another table to join; in the other table we have the calendarweek (both iso and us), quarter, month etc. the join is done with the date-part only. group by is then done via one of the additionalcolumns, that depends on the report (by week, by month etc)
the other table is filled one time with values for 100 years, thats enough for our requirements.
table schema:
CREATE TABLE [dbo].[PeriodeDate](
[Id] [int] NOT NULL IDENTITY(1, 1),
[periodeDate] [datetime] NOT NULL,
[periodQuarter] [int] NULL,
[periodYear] [int] NULL,
[periodMonth] [int] NULL,
[calendarWeekISO] [int] NULL,
[YearOfCalendarWeekISO] [int] NULL,
[YearOfCalendarWeekUS] [int] NULL,
[calendarWeekUS] [int] NULL,
)
and keep in mind, there are years which have 53! calendarweeks (both, ISO and US)
精彩评论