夏令時計算。下面我們有一個非常難看的工作模式。SQL非常難看GROUP BY
見過這個 - SQL - Ugly combination of GROUP BY and COALESCE
如果我們可以通過設置變量。這不工作 - 也已經刪除了COUNT(*),說明我們所看到的問題..
Declare @subtractor int;
select top 10 case
when LOGGED_TIME between
case DATEPART(dw,CAST('03/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime))
when 1 then dateadd(hh,-4,CAST('03/08/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime))--2am minus 6 hours for conversion from UST going to DST
else dateadd(hh,-4,DATEADD(d,15-datepart(dw,CAST('03/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime)),CAST('03/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime)))
end
and
case DATEPART(dw,CAST('11/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime))
when 1 then dateadd(hh,-3,CAST('11/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime)) --2am minus 5 hours for conversion from UST going from DST
else dateadd(hh,-3,DATEADD(d,8-datepart(dw,CAST('11/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime)),CAST('11/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime)))
end
then
Set @subtractor = 5;
else
Set @subtractor = 6;
end
CAST(DATEADD(HH, [email protected],LOGGED_TIME) AS date) AS ForDate
, txtW=DATENAME(WEEKDAY, DATEADD(HH, [email protected],LOGGED_TIME))
, intW=DATEPART(WEEKDAY, DATEADD(HH, [email protected],LOGGED_TIME))
, intH=DATEPART(HOUR, DATEADD(HH, [email protected],LOGGED_TIME))
from SUPPORT_DATABASE.dbo.LOG (nolock)
這是行得通的。但是,它是一個非常非常醜陋的GROUP BY ..有沒有辦法清理這個呢?
select top 10
case
when LOGGED_TIME between
case DATEPART(dw,CAST('03/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime))
when 1 then dateadd(hh,-4,CAST('03/08/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime))--2am minus 6 hours for conversion from UST going to DST
else dateadd(hh,-4,DATEADD(d,15-datepart(dw,CAST('03/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime)),CAST('03/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime)))
end
and
case DATEPART(dw,CAST('11/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime))
when 1 then dateadd(hh,-3,CAST('11/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime)) --2am minus 5 hours for conversion from UST going from DST
else dateadd(hh,-3,DATEADD(d,8-datepart(dw,CAST('11/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime)),CAST('11/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime)))
end
then CAST(dateadd(hh,-5,LOGGED_TIME) AS date) -- DST
else CAST(dateadd(hh,-6,LOGGED_TIME) AS date) -- DST
end as ForDate,
case
when LOGGED_TIME between
case DATEPART(dw,CAST('03/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime))
when 1 then dateadd(hh,-4,CAST('03/08/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime))--2am minus 6 hours for conversion from UST going to DST
else dateadd(hh,-4,DATEADD(d,15-datepart(dw,CAST('03/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime)),CAST('03/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime)))
end
and
case DATEPART(dw,CAST('11/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime))
when 1 then dateadd(hh,-3,CAST('11/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime)) --2am minus 5 hours for conversion from UST going from DST
else dateadd(hh,-3,DATEADD(d,8-datepart(dw,CAST('11/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime)),CAST('11/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime)))
end
then DATENAME(WEEKDAY,dateadd(hh,-5,LOGGED_TIME)) -- DST
else DATENAME(WEEKDAY,dateadd(hh,-6,LOGGED_TIME)) -- DST
end as txtW,
case
when LOGGED_TIME between
case DATEPART(dw,CAST('03/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime))
when 1 then dateadd(hh,-4,CAST('03/08/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime))--2am minus 6 hours for conversion from UST going to DST
else dateadd(hh,-4,DATEADD(d,15-datepart(dw,CAST('03/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime)),CAST('03/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime)))
end
and
case DATEPART(dw,CAST('11/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime))
when 1 then dateadd(hh,-3,CAST('11/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime)) --2am minus 5 hours for conversion from UST going from DST
else dateadd(hh,-3,DATEADD(d,8-datepart(dw,CAST('11/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime)),CAST('11/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime)))
end
then DATENAME(WEEKDAY,dateadd(hh,-5,LOGGED_TIME)) -- DST
else DATENAME(WEEKDAY,dateadd(hh,-6,LOGGED_TIME)) -- DST
end as intW,
case
when LOGGED_TIME between
case DATEPART(dw,CAST('03/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime))
when 1 then dateadd(hh,-4,CAST('03/08/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime))--2am minus 6 hours for conversion from UST going to DST
else dateadd(hh,-4,DATEADD(d,15-datepart(dw,CAST('03/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime)),CAST('03/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime)))
end
and
case DATEPART(dw,CAST('11/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime))
when 1 then dateadd(hh,-3,CAST('11/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime)) --2am minus 5 hours for conversion from UST going from DST
else dateadd(hh,-3,DATEADD(d,8-datepart(dw,CAST('11/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime)),CAST('11/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime)))
end
then DATEPART(HOUR,dateadd(hh,-5,LOGGED_TIME)) -- DST
else DATEPART(HOUR,dateadd(hh,-6,LOGGED_TIME)) -- DST
end as intH
, COUNT(*) AS Totals
FROM SUPPORT_DATABASE.dbo.LOG WITH (nolock)
GROUP BY case
when LOGGED_TIME between
case DATEPART(dw,CAST('03/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime))
when 1 then dateadd(hh,-4,CAST('03/08/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime))--2am minus 6 hours for conversion from UST going to DST
else dateadd(hh,-4,DATEADD(d,15-datepart(dw,CAST('03/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime)),CAST('03/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime)))
end
and
case DATEPART(dw,CAST('11/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime))
when 1 then dateadd(hh,-3,CAST('11/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime)) --2am minus 5 hours for conversion from UST going from DST
else dateadd(hh,-3,DATEADD(d,8-datepart(dw,CAST('11/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime)),CAST('11/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime)))
end
then CAST(dateadd(hh,-5,LOGGED_TIME) AS date) -- DST
else CAST(dateadd(hh,-6,LOGGED_TIME) AS date) -- DST
end,
case
when LOGGED_TIME between
case DATEPART(dw,CAST('03/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime))
when 1 then dateadd(hh,-4,CAST('03/08/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime))--2am minus 6 hours for conversion from UST going to DST
else dateadd(hh,-4,DATEADD(d,15-datepart(dw,CAST('03/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime)),CAST('03/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime)))
end
and
case DATEPART(dw,CAST('11/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime))
when 1 then dateadd(hh,-3,CAST('11/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime)) --2am minus 5 hours for conversion from UST going from DST
else dateadd(hh,-3,DATEADD(d,8-datepart(dw,CAST('11/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime)),CAST('11/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime)))
end
then DATENAME(WEEKDAY,dateadd(hh,-5,LOGGED_TIME)) -- DST
else DATENAME(WEEKDAY,dateadd(hh,-6,LOGGED_TIME)) -- DST
end
,
case
when LOGGED_TIME between
case DATEPART(dw,CAST('03/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime))
when 1 then dateadd(hh,-4,CAST('03/08/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime))--2am minus 6 hours for conversion from UST going to DST
else dateadd(hh,-4,DATEADD(d,15-datepart(dw,CAST('03/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime)),CAST('03/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime)))
end
and
case DATEPART(dw,CAST('11/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime))
when 1 then dateadd(hh,-3,CAST('11/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime)) --2am minus 5 hours for conversion from UST going from DST
else dateadd(hh,-3,DATEADD(d,8-datepart(dw,CAST('11/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime)),CAST('11/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime)))
end
then DATEPART(WEEKDAY,dateadd(hh,-5,LOGGED_TIME)) -- DST
else DATEPART(WEEKDAY,dateadd(hh,-6,LOGGED_TIME)) -- DST
end,
case
when LOGGED_TIME between
case DATEPART(dw,CAST('03/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime))
when 1 then dateadd(hh,-4,CAST('03/08/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime))--2am minus 6 hours for conversion from UST going to DST
else dateadd(hh,-4,DATEADD(d,15-datepart(dw,CAST('03/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime)),CAST('03/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime)))
end
and
case DATEPART(dw,CAST('11/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime))
when 1 then dateadd(hh,-3,CAST('11/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime)) --2am minus 5 hours for conversion from UST going from DST
else dateadd(hh,-3,DATEADD(d,8-datepart(dw,CAST('11/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime)),CAST('11/01/'+CAST (YEAR(LOGGED_TIME) as varchar(4)) as datetime)))
end
then DATEPART(HOUR,dateadd(hh,-5,LOGGED_TIME)) -- DST
else DATEPART(HOUR,dateadd(hh,-6,LOGGED_TIME)) -- DST
end
適用於需要重構的代碼 - http://codereview.stackexchange.com/ – EkoostikMartin