开发者

Sorting/Grouping SQL by day-of-week and hour-of-day

开发者 https://www.devze.com 2023-03-29 20:44 出处:网络
I have a SQL Server 2005 table that contains records with a UTC/GMT date field. I need to have the records GROUPed BY and ORDERed by the \"day of the week\" and \"hour of the day\".Giving 7*24=168 gro

I have a SQL Server 2005 table that contains records with a UTC/GMT date field. I need to have the records GROUPed BY and ORDERed by the "day of the week" and "hour of the day". Giving 7*24=168 groups. The output would look like:

Sun 12am
Sun  1am
Sun  2am
.... etc
Mon 12am
Mon  1am
.... etc
.... etc
Sat 10pm
Sat 11pm

Everything works fine until I try to convert things to my local time zone. Doing the conversion inside SQL:

SELECT MIN(Key),MIN(SavedOn), 
FROM MyTable 
GROUP BY (DatePart(WEEKDAY, SavedOn)*24.0) + DatePart(HOUR, SavedOn) - (5.0/24.0)
ORDER BY (DatePart(WEEKDAY, SavedOn)*24.0) + DatePart(HOUR, SavedOn) - (5.0/24.0)
开发者_运维问答

Or doing the conversion in my own code AFTER sorting/getting the records in UTC:

SELECT MIN(Key),MIN(SavedOn), 
FROM MyTable 
GROUP BY (DatePart(WEEKDAY, SavedOn)*24.0) + DatePart(HOUR, SavedOn)  
ORDER BY (DatePart(WEEKDAY, SavedOn)*24.0) + DatePart(HOUR, SavedOn) 

(my own math here)

Either way... 5 records will appear "out of order". The end of the week records (Sat PM) appear at the beginning of the week... not the end... where they belong.

Any idea on what I'm doing wrong?


Floating point math is imprecise. Multiplying by 24.0 invites border errors.

Instead of adding the numbers

GROUP BY (DatePart(WEEKDAY, SavedOn)*24.0) + DatePart(HOUR, SavedOn)  

sort on two fields instead:

GROUP BY DatePart(WEEKDAY, SavedOn), DatePart(HOUR, SavedOn) 


Here is what I would do. I am not sure I totally understand what you are trying though:

SELECT DatePart(WEEKDAY, SavedOn), DatePart(HOUR, SavedOn) , min(key)
FROM MyTable 
GROUP BY DatePart(WEEKDAY, SavedOn), DatePart(HOUR, SavedOn)
ORDER BY 1, 2

If your approach to converting is just to add 5 hours, then do it every time you see SavedOn , like this:

SELECT DatePart(WEEKDAY, SavedOn+5.0/24.0), DatePart(HOUR, SavedOn+5.0/24.0) , min(key)
FROM MyTable 
GROUP BY DatePart(WEEKDAY, SavedOn+5.0/24.0, DatePart(HOUR, SavedOn+5.0/24.0)
ORDER BY 1, 2
0

精彩评论

暂无评论...
验证码 换一张
取 消