| Author |
Topic |
|
hamble18
Starting Member
12 Posts |
Posted - 2008-08-14 : 09:46:59
|
| Hello all. I've been tearing my hair out on this one for days but my SQL skills just aren't up to it. Hopefully someone here will enjoy the challenge.I have the following tables (abridged):Delegates- ID int- Name varcharAttendance- ID int- DelegateID int- AttendTime datetime- AttendDate datetime (this is a computed field to extract just the date from AttendTime to simplify queries. It is defined by formula: (dateadd(day,(0),datediff(day,(0),[AttendTime])))If people go in and out during the day, they will receive multiple records in Attendance every time they go in. I need to summarize the data as follows:For each day and hour, how many new people are there (i.e. this is the first time they have attended the event) AND how many people are there for the first time today (i.e. this is the first time they have entered the building on that particular day)So, for example, someone who entered the building at the following times:1st Jan 09:051st Jan 13:202nd Jan 10:504th Jan 08:404th Jan 12:40would be counted in the "1st Jan 09:00-09:59" row in the first column,(i.e. each person just the first time/date they entered) and would be counted in the "1st Jan 09:00-09:59", "2nd Jan 10:00-10:59", "4th Jan 08:00-08:59" rows in the second column.(i.e. the earliest hour on each day they entered, but only counted once a day)Ideally; because I need to build this into a larger thing, I would like to achieve this using a single statement. I don't see how it is doable. Can you? |
|
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2008-08-14 : 10:09:54
|
[code]DECLARE @Sample TABLE ( DelegateID INT, AttendTime DATETIME )INSERT @SampleSELECT 1, 'Jan 1, 2008 09:05' UNION ALLSELECT 2, 'Jan 1, 2008 09:06' UNION ALLSELECT 1, 'Jan 1, 2008 13:20' UNION ALLSELECT 1, 'Jan 2, 2008 10:50' UNION ALLSELECT 2, 'Jan 3, 2008 11:11' UNION ALLSELECT 1, 'Jan 4, 2008 08:40' UNION ALLSELECT 1, 'Jan 4, 2008 12:40'-- NormalizedSELECT theFirstAttend AS theAttendHour, COUNT(*) AS theAttendsFROM ( SELECT DATEADD(HOUR, DATEDIFF(HOUR, '19000101', MIN(AttendTime)), '19000101') AS theFirstAttend FROM @Sample GROUP BY DATEDIFF(DAY, '19000101', AttendTime), DelegateID ) AS dGROUP BY theFirstAttendORDER BY theFirstAttend-- DenormalizedSELECT CONVERT(CHAR(5), theFirstAttend, 108) AS theHour, SUM(CASE WHEN DATEPART(DAY, theFirstAttend) = 1 THEN 1 ELSE 0 END) AS Jan1, SUM(CASE WHEN DATEPART(DAY, theFirstAttend) = 2 THEN 1 ELSE 0 END) AS Jan2, SUM(CASE WHEN DATEPART(DAY, theFirstAttend) = 3 THEN 1 ELSE 0 END) AS Jan3, SUM(CASE WHEN DATEPART(DAY, theFirstAttend) = 4 THEN 1 ELSE 0 END) AS Jan4FROM ( SELECT DATEADD(HOUR, DATEDIFF(HOUR, '19000101', MIN(AttendTime)), '19000101') AS theFirstAttend FROM @Sample GROUP BY DATEDIFF(DAY, '19000101', AttendTime), DelegateID ) AS dGROUP BY CONVERT(CHAR(5), theFirstAttend, 108)ORDER BY CONVERT(CHAR(5), theFirstAttend, 108)[/code] E 12°55'05.25"N 56°04'39.16" |
 |
|
|
hamble18
Starting Member
12 Posts |
Posted - 2008-08-14 : 10:15:57
|
Wow Peso, that was quick! Interesting use of '19000101'.This gives me the second column that I need, and I can see that (taking your normalized version) by removing part of the GROUP BY in the middle I get the first column:SELECT theFirstAttend AS theAttendHour, COUNT(*) AS theAttendsFROM ( SELECT DATEADD(HOUR, DATEDIFF(HOUR, '19000101', MIN(AttendTime)), '19000101') AS theFirstAttend FROM @Sample GROUP BY DelegateID ) AS dGROUP BY theFirstAttendORDER BY theFirstAttend Can I easily put these together into a single select to return both pieces of information at the same time? |
 |
|
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2008-08-14 : 10:20:59
|
[code]DECLARE @Sample TABLE ( DelegateID INT, AttendTime DATETIME )INSERT @SampleSELECT 1, 'Jan 1, 2008 09:05' UNION ALLSELECT 2, 'Jan 1, 2008 09:06' UNION ALLSELECT 1, 'Jan 1, 2008 13:20' UNION ALLSELECT 1, 'Jan 2, 2008 10:50' UNION ALLSELECT 2, 'Jan 3, 2008 11:11' UNION ALLSELECT 3, 'Jan 4, 2008 08:40' UNION ALLSELECT 1, 'Jan 4, 2008 12:40'-- NormalizedSELECT theFirstAttend AS theAttendHour, SUM(theFirstAttendToday) AS theFirstAttendToday, SUM(theFirstAttendEver) AS theFirstAttendEverFROM ( SELECT DATEADD(HOUR, DATEDIFF(HOUR, '19000101', MIN(AttendTime)), '19000101') AS theFirstAttend, 1 AS theFirstAttendToday, 0 AS theFirstAttendEver FROM @Sample GROUP BY DATEDIFF(DAY, '19000101', AttendTime), DelegateID UNION ALL SELECT DATEADD(HOUR, DATEDIFF(HOUR, '19000101', MIN(AttendTime)), '19000101'), 0, 1 FROM @Sample GROUP BY DelegateID ) AS dGROUP BY theFirstAttendORDER BY theFirstAttend-- DenormalizedSELECT CONVERT(CHAR(5), theFirstAttend, 108) AS theHour, SUM(CASE WHEN DATEPART(DAY, theFirstAttend) = 1 THEN 1 ELSE 0 END) AS Jan1, SUM(CASE WHEN DATEPART(DAY, theFirstAttend) = 2 THEN 1 ELSE 0 END) AS Jan2, SUM(CASE WHEN DATEPART(DAY, theFirstAttend) = 3 THEN 1 ELSE 0 END) AS Jan3, SUM(CASE WHEN DATEPART(DAY, theFirstAttend) = 4 THEN 1 ELSE 0 END) AS Jan4FROM ( SELECT DATEADD(HOUR, DATEDIFF(HOUR, '19000101', MIN(AttendTime)), '19000101') AS theFirstAttend FROM @Sample GROUP BY DATEDIFF(DAY, '19000101', AttendTime), DelegateID ) AS dGROUP BY CONVERT(CHAR(5), theFirstAttend, 108)ORDER BY CONVERT(CHAR(5), theFirstAttend, 108)[/code] E 12°55'05.25"N 56°04'39.16" |
 |
|
|
hamble18
Starting Member
12 Posts |
Posted - 2008-08-14 : 10:28:32
|
| Thank you so much. I really do appreciate it. There's so much for me to learn from that.Thanks Again. |
 |
|
|
|
|
|