Produce a PIVOT table - sql
I am trying to find the best way to produce the following table in a report (rdlc) -
This is showing the teacher name on the far left column (pulled from a teachers table), then bookings from Monday to Friday (pulled from a bookingdays table). In the rows, an AM booking (BookingDuration: 0) will be in the top row, a PM booking (BookingDuration: 1) will be in the bottom row and finally a Full Day (BookingDuration: 2) will be in the top row but in upper case (dealt with in the RDLC).
The problem I am having is producing a table from SQL that is speedy and tidy. I believe I need to produce a PIVOT table, however I have tried many different methods.
There is also hourly bookings to consider (BookingDuration: 3). Each booking day has a start and end time. so if the start time is < 12:00 and the end time is > 12:00, full day. If start and end time < 12:00 then AM and finally if the end time and start time > 12:00, Full day. There may also be 2x AM hourly bookings (09:00- 10:00 and 10:30 - 11:30) but never more than 2. The same applies to PM. When this happens, the first AM will be in the top box and the second AM will be in the bottom box. I have been assured that 2x AM and 1x PM booking will never occur, so I have added validation in the create booking form to prevent this.
There is a row for every teacher. When a teacher has no bookings, the teacher will still be shown on the report but the values will be empty.
My table (BookingDays) is as follows -
ID - INT(PK)
BookingID - INT
BookingDate - date
DayText - VARCHAR(50)
StartTIme - decimal
EndTime - decimal
TeacherID int
BookingDuration - int
NoOfHours - decimal
TotalChargeAmount - decimal
TotalPayAmount - decimal
Status - int
There is also a teachers table containing Full name etc. This is joined to the BookingDays table by the TeacherID column.
Does anyone have any idea how I can go about doing this?
This is what I have tried so far (showing only Friday due to text limit). The problem with this one is I can't get the AM/PM hourly's showing if there is 2 -
with CTE_D as
(
SELECT DATEADD(ww, DATEDIFF(ww,0,CONVERT(date, #WeekStart, 103)), 0) as BookingDate
union all
select DATEADD(day, 1, BookingDate)
from CTE_D where BookingDate < DATEADD(ww, DATEDIFF(ww,0,CONVERT(date, #WeekStart, 103)), 6)
)
SELECT
t.Firstname,
t.Surname, t.Telephone, t.Mobile, t.Band, tb.Band, t.DefaultChargeRateDaily as 'TeacherDefaultChargeRateDaily', t.DefaultPayRateDaily as 'TeacherDefaultPayRateDaily', t.DefaultChargeRateAM, t.DefaultChargeRatePM, t.DefaultChargeRateDaily, t.DefaultPayRateAM, t.DefaultPayRatePM, t.DefaultPayRateDaily,
--------------------------------------------------------------------------------------------------------------------------
MIN(CASE WHEN bd.DayText = 'Friday' and bd.BookingDuration = 0 and s.PrimarySchool = 1 THEN s.SchoolName ELSE NULL END) "FridayAM",
MIN(CASE WHEN bd.DayText = 'Friday' and bd.BookingType = 0 and bd.BookingDuration = 0 and s.PrimarySchool = 1 THEN bd.TotalChargeAmount ELSE NULL END) "FridayAMTotalChargeAmount",
MIN(CASE WHEN bd.DayText = 'Friday' and bd.BookingType = 0 and bd.BookingDuration = 0 and s.PrimarySchool = 1 THEN bd.TotalPayAmount ELSE NULL END) "FridayAMTotalPayAmount",
MIN(CASE WHEN bd.DayText = 'Friday' and bd.BookingType = 0 and bd.BookingDuration = 0 and s.PrimarySchool = 1 THEN bd.BandBookedAt ELSE NULL END) "FridayAMBandBookedAt",
MIN(CASE WHEN bd.DayText = 'Friday' and bd.BookingDuration = 1 and s.PrimarySchool = 1 THEN s.SchoolName ELSE NULL END) "FridayPM",
MIN(CASE WHEN bd.DayText = 'Friday' and bd.BookingType = 0 and bd.BookingDuration = 1 and s.PrimarySchool = 1 THEN bd.TotalChargeAmount ELSE NULL END) "FridayPMTotalChargeAmount",
MIN(CASE WHEN bd.DayText = 'Friday' and bd.BookingType = 0 and bd.BookingDuration = 1 and s.PrimarySchool = 1 THEN bd.TotalPayAmount ELSE NULL END) "FridayPMTotalPayAmount",
MIN(CASE WHEN bd.DayText = 'Friday' and bd.BookingType = 0 and bd.BookingDuration = 1 and s.PrimarySchool = 1 THEN bd.BandBookedAt ELSE NULL END) "FridayPMBandBookedAt",
MIN(CASE WHEN bd.DayText = 'Friday' and bd.BookingDuration = 2 and s.PrimarySchool = 1 THEN s.SchoolName ELSE NULL END) "FridayDaily",
MIN(CASE WHEN bd.DayText = 'Friday' and bd.BookingType = 0 and bd.BookingDuration = 2 and s.PrimarySchool = 1 THEN bd.TotalChargeAmount ELSE NULL END) "FridayDailyTotalChargeAmount",
MIN(CASE WHEN bd.DayText = 'Friday' and bd.BookingType = 0 and bd.BookingDuration = 2 and s.PrimarySchool = 1 THEN bd.TotalPayAmount ELSE NULL END) "FridayDailyTotalPayAmount",
MIN(CASE WHEN bd.DayText = 'Friday' and bd.BookingType = 0 and bd.BookingDuration = 2 and s.PrimarySchool = 1 THEN bd.BandBookedAt ELSE NULL END) "FridayDailyBandBookedAt",
COUNT(DISTINCT CASE WHEN bd.DayText = 'Friday' and bd.BookingDuration = 3 and CONVERT(time(0), bd.StartTime) < CONVERT(time(0), '12:00:00') AND bd.NoOfHOurs < 5.5 and s.PrimarySchool = 1 THEN bd.ID END) as "FridayHourlyAMCount",
MAX(CASE WHEN bd.DayText = 'Friday' and bd.BookingDuration = 3 and CONVERT(time(0), bd.StartTime) < CONVERT(time(0), '12:00:00') AND bd.NoOfHOurs < 5.5 and s.PrimarySchool = 1 THEN bd.ID ELSE NULL END) "FridayHourlyAM",
MAX(CASE WHEN bd.DayText = 'Friday' and bd.BookingDuration = 3 and CONVERT(time(0), bd.StartTime) < CONVERT(time(0), '12:00:00') AND bd.NoOfHOurs < 5.5 and s.PrimarySchool = 1 THEN s.SchoolName ELSE NULL END) "FridayHourlyAMSchoolName",
MAX(CASE WHEN bd.DayText = 'Friday' and bd.BookingDuration = 3 and CONVERT(time(0), bd.StartTime) < CONVERT(time(0), '12:00:00') AND bd.NoOfHOurs < 5.5 and s.PrimarySchool = 1 THEN REPLACE(REPLACE(LTRIM(RIGHT(CONVERT(VARCHAR, bd.StartTime, 100), 7)) + '-' + LTRIM(RIGHT(CONVERT(VARCHAR(20), bd.EndTime, 100), 7)), 'AM',''), 'PM', '') ELSE NULL END) "FridayHourlyAMTimes",
MAX(CASE WHEN bd.DayText = 'Friday' and bd.BookingDuration = 3 and CONVERT(time(0), bd.StartTime) < CONVERT(time(0), '12:00:00') AND bd.NoOfHOurs < 5.5 and s.PrimarySchool = 1 THEN bd.TotalChargeAmount ELSE NULL END) "FridayHourlyAMTotalChargeAmount",
MAX(CASE WHEN bd.DayText = 'Friday' and bd.BookingDuration = 3 and CONVERT(time(0), bd.StartTime) < CONVERT(time(0), '12:00:00') AND bd.NoOfHOurs < 5.5 and s.PrimarySchool = 1 THEN bd.TotalPayAmount ELSE NULL END) "FridayHourlyAMTotalPayAmount",
MAX(CASE WHEN bd.DayText = 'Friday' and bd.BookingDuration = 3 and CONVERT(time(0), bd.StartTime) < CONVERT(time(0), '12:00:00') AND bd.NoOfHOurs < 5.5 and s.PrimarySchool = 1 THEN bd.BandBookedAt ELSE NULL END) "FridayHourlyAMBandBookedAt",
MIN(CASE WHEN bd.DayText = 'Friday' and bd.BookingDuration = 3 and CONVERT(time(0), bd.StartTime) < CONVERT(time(0), '12:00:00') AND bd.NoOfHOurs < 5.5 and s.PrimarySchool = 1 THEN bd.ID ELSE NULL END) "FridayHourlyAM2",
MIN(CASE WHEN bd.DayText = 'Friday' and bd.BookingDuration = 3 and CONVERT(time(0), bd.StartTime) < CONVERT(time(0), '12:00:00') AND bd.NoOfHOurs < 5.5 and s.PrimarySchool = 1 THEN s.SchoolName ELSE NULL END) "FridayHourlyAM2SchoolName",
MIN(CASE WHEN bd.DayText = 'Friday' and bd.BookingDuration = 3 and CONVERT(time(0), bd.StartTime) < CONVERT(time(0), '12:00:00') AND bd.NoOfHOurs < 5.5 and s.PrimarySchool = 1 THEN REPLACE(REPLACE(LTRIM(RIGHT(CONVERT(VARCHAR, bd.StartTime, 100), 7)) + '-' + LTRIM(RIGHT(CONVERT(VARCHAR(20), bd.EndTime, 100), 7)), 'AM',''), 'PM', '') ELSE NULL END) "FridayHourlyAM2Times",
MIN(CASE WHEN bd.DayText = 'Friday' and bd.BookingDuration = 3 and CONVERT(time(0), bd.StartTime) < CONVERT(time(0), '12:00:00') AND bd.NoOfHOurs < 5.5 and s.PrimarySchool = 1 THEN bd.TotalChargeAmount ELSE NULL END) "FridayHourlyAM2TotalChargeAmount",
MIN(CASE WHEN bd.DayText = 'Friday' and bd.BookingDuration = 3 and CONVERT(time(0), bd.StartTime) < CONVERT(time(0), '12:00:00') AND bd.NoOfHOurs < 5.5 and s.PrimarySchool = 1 THEN bd.TotalPayAmount ELSE NULL END) "FridayHourlyAM2TotalPayAmount",
MIN(CASE WHEN bd.DayText = 'Friday' and bd.BookingDuration = 3 and CONVERT(time(0), bd.StartTime) < CONVERT(time(0), '12:00:00') AND bd.NoOfHOurs < 5.5 and s.PrimarySchool = 1 THEN bd.BandBookedAt ELSE NULL END) "FridayHourlyAM2BandBookedAt",
COUNT(DISTINCT CASE WHEN bd.DayText = 'Friday' and bd.BookingDuration = 3 and CONVERT(time(0), bd.StartTime) >= CONVERT(time(0), '12:00:00') and bd.NoOfHours < 5.5 and s.PrimarySchool = 1 THEN bd.ID END) as "FridayHourlyPMCount",
MAX(CASE WHEN bd.DayText = 'Friday' and bd.BookingDuration = 3 and CONVERT(time(0), bd.StartTime) >= CONVERT(time(0), '12:00:00') and bd.NoOfHours < 5.5 AND s.PrimarySchool = 1 THEN bd.ID ELSE NULL END) "FridayHourlyPM",
MAX(CASE WHEN bd.DayText = 'Friday' and bd.BookingDuration = 3 and CONVERT(time(0), bd.StartTime) >= CONVERT(time(0), '12:00:00') and bd.NoOfHours < 5.5 AND s.PrimarySchool = 1 THEN s.SchoolName ELSE NULL END) "FridayHourlyPMSchoolName",
MAX(CASE WHEN bd.DayText = 'Friday' and bd.BookingDuration = 3 and CONVERT(time(0), bd.StartTime) >= CONVERT(time(0), '12:00:00') and bd.NoOfHours < 5.5 AND s.PrimarySchool = 1 THEN REPLACE(REPLACE(LTRIM(RIGHT(CONVERT(VARCHAR, bd.StartTime, 100), 7)) + '-' + LTRIM(RIGHT(CONVERT(VARCHAR(20), bd.EndTime, 100), 7)), 'AM',''), 'PM', '') ELSE NULL END) "FridayHourlyPMTimes",
MAX(CASE WHEN bd.DayText = 'Friday' and bd.BookingDuration = 3 and CONVERT(time(0), bd.StartTime) >= CONVERT(time(0), '12:00:00') and bd.NoOfHours < 5.5 AND s.PrimarySchool = 1 THEN bd.TotalChargeAmount ELSE NULL END) "FridayHourlyPMTotalChargeAmount",
MAX(CASE WHEN bd.DayText = 'Friday' and bd.BookingDuration = 3 and CONVERT(time(0), bd.StartTime) >= CONVERT(time(0), '12:00:00') and bd.NoOfHours < 5.5 AND s.PrimarySchool = 1 THEN bd.TotalPayAmount ELSE NULL END) "FridayHourlyPMTotalPayAmount",
MAX(CASE WHEN bd.DayText = 'Friday' and bd.BookingDuration = 3 and CONVERT(time(0), bd.StartTime) >= CONVERT(time(0), '12:00:00') and bd.NoOfHours < 5.5 AND s.PrimarySchool = 1 THEN bd.BandBookedAt ELSE NULL END) "FridayHourlyPMBandBookedAt",
MIN(CASE WHEN bd.DayText = 'Friday' and bd.BookingDuration = 3 and CONVERT(time(0), bd.StartTime) >= CONVERT(time(0), '12:00:00') and bd.NoOfHours < 5.5 AND s.PrimarySchool = 1 THEN bd.ID ELSE NULL END) "FridayHourlyPM2",
MIN(CASE WHEN bd.DayText = 'Friday' and bd.BookingDuration = 3 and CONVERT(time(0), bd.StartTime) >= CONVERT(time(0), '12:00:00') and bd.NoOfHours < 5.5 AND s.PrimarySchool = 1 THEN s.SchoolName ELSE NULL END) "FridayHourlyPM2SchoolName",
MIN(CASE WHEN bd.DayText = 'Friday' and bd.BookingDuration = 3 and CONVERT(time(0), bd.StartTime) >= CONVERT(time(0), '12:00:00') and bd.NoOfHours < 5.5 AND s.PrimarySchool = 1 THEN REPLACE(REPLACE(LTRIM(RIGHT(CONVERT(VARCHAR, bd.StartTime, 100), 7)) + '-' + LTRIM(RIGHT(CONVERT(VARCHAR(20), bd.EndTime, 100), 7)), 'AM',''), 'PM', '') ELSE NULL END) "FridayHourlyPM2Times",
MIN(CASE WHEN bd.DayText = 'Friday' and bd.BookingDuration = 3 and CONVERT(time(0), bd.StartTime) >= CONVERT(time(0), '12:00:00') and bd.NoOfHours < 5.5 AND s.PrimarySchool = 1 THEN bd.TotalChargeAmount ELSE NULL END) "FridayHourlyPM2TotalChargeAmount",
MIN(CASE WHEN bd.DayText = 'Friday' and bd.BookingDuration = 3 and CONVERT(time(0), bd.StartTime) >= CONVERT(time(0), '12:00:00') and bd.NoOfHours < 5.5 AND s.PrimarySchool = 1 THEN bd.TotalPayAmount ELSE NULL END) "FridayHourlyPM2TotalPayAmount",
MIN(CASE WHEN bd.DayText = 'Friday' and bd.BookingDuration = 3 and CONVERT(time(0), bd.StartTime) >= CONVERT(time(0), '12:00:00') and bd.NoOfHours < 5.5 AND s.PrimarySchool = 1 THEN bd.BandBookedAt ELSE NULL END) "FridayHourlyPM2BandBookedAt",
MIN(CASE WHEN bd.DayText = 'Friday' and bd.BookingDuration = 3 and bd.NoOfHours >= 5.5 and s.PrimarySchool = 1 AND CONVERT(time(0), bd.EndTime) > CONVERT(time(0), '12:00:00') THEN bd.ID ELSE NULL END) "FridayHourlyFullDay",
MIN(CASE WHEN bd.DayText = 'Friday' and bd.BookingDuration = 3 and bd.NoOfHours >= 5.5 and s.PrimarySchool = 1 AND CONVERT(time(0), bd.EndTime) > CONVERT(time(0), '12:00:00') THEN s.SchoolName ELSE NULL END) "FridayHourlyFullDaySchoolName",
MIN(CASE WHEN bd.DayText = 'Friday' and bd.BookingDuration = 3 and bd.NoOfHours >= 5.5 and s.PrimarySchool = 1 AND CONVERT(time(0), bd.EndTime) > CONVERT(time(0), '12:00:00') THEN REPLACE(REPLACE(LTRIM(RIGHT(CONVERT(VARCHAR, bd.StartTime, 100), 7)) + '-' + LTRIM(RIGHT(CONVERT(VARCHAR(20), bd.EndTime, 100), 7)), 'AM',''), 'PM', '') ELSE NULL END) "FridayHourlyFullDayTimes",
MIN(CASE WHEN bd.DayText = 'Friday' and bd.BookingDuration = 3 and bd.NoOfHours >= 5.5 and s.PrimarySchool = 1 AND CONVERT(time(0), bd.EndTime) > CONVERT(time(0), '12:00:00') THEN bd.TotalChargeAmount ELSE NULL END) "FridayHourlyFullDayTotalChargeAmount",
MIN(CASE WHEN bd.DayText = 'Friday' and bd.BookingDuration = 3 and bd.NoOfHours >= 5.5 and s.PrimarySchool = 1 AND CONVERT(time(0), bd.EndTime) > CONVERT(time(0), '12:00:00') THEN bd.TotalPayAmount ELSE NULL END) "FridayHourlyFullDayTotalPayAmount",
MIN(CASE WHEN bd.DayText = 'Friday' and bd.BookingDuration = 3 and bd.NoOfHours >= 5.5 and s.PrimarySchool = 1 AND CONVERT(time(0), bd.EndTime) > CONVERT(time(0), '12:00:00') THEN bd.BandBookedAt ELSE NULL END) "FridayFullDayBandBookedAt",
COUNT(CASE WHEN s.PrimarySchool = 1 THEN bd.ID ELSE NULL END) "BookingCount",
--------------------------------------------------------------------------------------------------------------------------
t.Notes, t.DefaultChargeRateDaily, t.DefaultPayRateDaily
FROM Teachers t
cross join CTE_D d
inner join TeacherBands tb
on t.Band = tb.ID
left join BookingDays bd
on t.ID = bd.TeacherID and
bd.BookingDate = d.BookingDate and bd.BookingType = 0
left join BookingDurations bds
on bd.BookingDuration = bds.ID
left join BookingTypes bt
on bd.BookingType = bt.ID
left join Bookings b
on bd.BookingID = b.ID
left join Schools s
on b.School = s.ID and s.PrimarySchool = 1
WHERE Active = 0 and (bd.Status = 0 or bd.Status IS NULL) and (t.Status != 2) and t.PrimarySchool = 1
GROUP BY Firstname, Surname, t.Telephone, t.Mobile, t.Notes, t.Band, tb.Band, t.DefaultPayRateDaily, t.DefaultChargeRateDaily, t.DefaultChargeRateAM, t.DefaultChargeRatePM, t.DefaultChargeRateDaily, t.DefaultPayRateAM, t.DefaultPayRatePM, t.DefaultPayRateDaily
ORDER BY Surname, Firstname ASC
Hope this makes sense. I have tried to adapt a pivot table I have used previously, however to no avail. I can't seem to get the school name displayed when it outputs to the final columns.
WITH Bookings AS
( SELECT TeacherID,
[WeekDay] = DATENAME(WEEKDAY, BookingDate),
[0], [1], [2], [3],
[Status] = CASE
WHEN ([0] > 0 AND [1] > 0) THEN 'XXX'
WHEN [2] > 0 THEN 'XXX'
WHEN [0] > 0 THEN 'PM'
WHEN [1] > 0 THEN 'AM'
WHEN [3] > 0 AND StartTime <= CONVERT(TIME, '12:00:00') AND EndTime >= CONVERT(TIME, '12:00:00') THEN 'XXX'
WHEN [3] > 0 AND EndTime <= CONVERT(TIME, '12:00:00') THEN 'PM'
WHEN [3] > 0 AND StartTime >= CONVERT(TIME, '12:00:00') THEN 'AM'
END
FROM ( SELECT TeacherID,
BookingDate,
BookingDuration,
StartTime = CASE WHEN BookingDuration = 3 THEN CAST(MIN(StartTime) OVER(PARTITION BY TeacherID, BookingDate, BookingDuration) AS TIME) ELSE NULL END,
EndTime = CASE WHEN BookingDuration = 3 THEN CAST(MAX(EndTime) OVER(PARTITION BY TeacherID, BookingDate, BookingDuration) AS TIME) ELSE NULL END,
[x] = 1
FROM BookingDays bd
WHERE (Status = 0 OR Status IS NULL)
) BookingDays
PIVOT
( SUM(x)
FOR BookingDuration IN ([0], [1], [2], [3])
) pvt
WHERE BookingDate >= DATEADD(ww, DATEDIFF(ww,0,'06/17/2013'), 0) AND BookingDate <= DATEADD(ww, DATEDIFF(ww,0,'06/17/2013'), 6)
), PivotedBookings AS
( SELECT *
FROM Bookings
PIVOT
( MAX([Status])
FOR [WeekDay] IN ([MondayAM1], [MondayAM2], [MondayPM1], [MondayPM2], [MondayFullDay])
) pvt
)
SELECT ID,Firstname,Surname,Band,'£' + CONVERT(varchar(50),DefaultChargeRateDaily) + '/' + '£' + CONVERT(varchar(50), DefaultPayRateDaily) as 'BandRates',Telephone,Mobile,Teacher,TeacherAssistant,KeyStage,MAX(MondayAM1) MondayAM1,MAX(MondayAM2) MondayAM2,MAX(MondayPM1) MondayPM1,MAX(MondayPM2) MondayPM2,MAX(MondayFullDay) MondayFullDay, Notes
FROM (
SELECT t.ID,
t.Firstname,
t.Surname,
tb.Band,
t.DefaultChargeRateDaily,
t.DefaultPayRateDaily,
t.Telephone,
t.Mobile,
t.Teacher,
t.TeacherAssistant,
CASE WHEN t.Nursery > 0 THEN 'NUR' WHEN t.Reception > 0 THEN 'REC' WHEN t.Year1 > 0 THEN 'Y1' WHEN t.Year2 > 0 THEN 'Y2' WHEN t.Year3 > 0 THEN 'Y3' WHEN t.Year4 > 0 THEN 'Y4' WHEN t.Year5 > 0 THEN 'Y5' WHEN t.Year6 > 0 THEN 'Y6' WHEN t.Year7 > 0 THEN 'Y7' WHEN t.Year8 > 0 THEN 'Y8' WHEN t.Year9 > 0 THEN 'Y9' WHEN t.Year10 > 0 THEN 'Y10' WHEN t.Year11 > 0 THEN 'Y11' WHEN t.ALevel > 0 THEN 'ALevel' END + ' - ' + CASE WHEN t.ALevel > 0 THEN 'ALevel' WHEN t.Year11 > 0 THEN 'Y11' WHEN t.Year10 > 0 THEN 'Y10' WHEN t.Year9 > 0 THEN 'Y9' WHEN t.Year8 > 0 THEN 'Y8' WHEN t.Year7 > 0 THEN 'Y7' WHEN t.Year6 > 0 THEN 'Y6' WHEN t.Year5 > 0 THEN 'Y5' WHEN t.Year4 > 0 THEN 'Y4' WHEN t.Year3 > 0 THEN 'Y3' WHEN t.Year2 > 0 THEN 'Y2' WHEN t.Year1 > 0 THEN 'Y1' WHEN t.Reception > 0 THEN 'REC' WHEN t.Nursery > 0 THEN 'NUR' ELSE '' END as 'KeyStage',
MondayAM1 = CASE WHEN an.Date = DATEADD(ww, DATEDIFF(ww,0,'06/17/2013'), 0) AND an.TeacherID = t.ID THEN an.Text WHEN t.Status = 0 THEN 'XXX' ELSE COALESCE(pb.MondayAM1, '') END,
MondayAM2 = CASE WHEN an.Date = DATEADD(ww, DATEDIFF(ww,0,'06/17/2013'), 0) AND an.TeacherID = t.ID THEN an.Text WHEN t.Status = 0 THEN 'XXX' ELSE COALESCE(pb.MondayAM2, '') END,
MondayPM1 = CASE WHEN an.Date = DATEADD(ww, DATEDIFF(ww,0,'06/17/2013'), 0) AND an.TeacherID = t.ID THEN an.Text WHEN t.Status = 0 THEN 'XXX' ELSE COALESCE(pb.MondayPM1, '') END,
MondayPM2 = CASE WHEN an.Date = DATEADD(ww, DATEDIFF(ww,0,'06/17/2013'), 0) AND an.TeacherID = t.ID THEN an.Text WHEN t.Status = 0 THEN 'XXX' ELSE COALESCE(pb.MondayPM2, '') END,
MondayFullDay = CASE WHEN an.Date = DATEADD(ww, DATEDIFF(ww,0,'06/17/2013'), 0) AND an.TeacherID = t.ID THEN an.Text WHEN t.Status = 0 THEN 'XXX' ELSE COALESCE(pb.MondayFullDay, '') END,
Notes
FROM Teachers t
LEFT JOIN PivotedBookings pb
ON pb.TeacherID = t.ID
LEFT JOIN TeacherBands tb
ON tb.ID = t.Band
LEFT JOIN AvailabilityNotes an
ON t.ID = an.TeacherID
WHERE t.Active = 0 and (t.Status = 1 or t.Status = 0) and t.PrimarySchool = 1
) T1
GROUP BY ID,Firstname,Surname,Telephone,Mobile,Teacher,TeacherAssistant,KeyStage,Notes,DefaultChargeRateDaily,DefaultPayRateDaily,Band
ORDER BY Surname,Firstname asc
Related
How can I avoid using "SET DATEFIRST 1" instruction?
I need to use the "DirectQuery" function on PowerBI Desktop. When i try to load the data PBI stops the process because of the "SET DATEFIRST 1" instruction at the beginning of the query. That happens because PBI elaborates the request like 'SELECT * FROM (Myquery)' and that throws a syntax error near "SET". I'm asking you if there is a way that allows me to set Monday as the first day of the week without using the "SET DATEFIRST 1" instruction. Here it is the query i'm talking about: SET DATEFIRST 1; SELECT SUM(Tabella2.DC20) AS DC20, SUM(Tabella2.OT20) AS OT20, SUM(Tabella2.FR20) AS FR20, SUM(Tabella2.RF20) AS RF20, SUM(Tabella2.DC40) AS DC40, SUM(Tabella2.OT40) AS OT40, SUM(Tabella2.FR40) AS FR40, SUM(Tabella2.RH40) AS RH40, SUM(Tabella2.HC40) AS HC40, SUM(Tabella2.HP40) AS HW40, SUM(Tabella2.HC45) AS HC45, SUM(Tabella2.HP45) AS HP45, SUM(Tabella2.Altri) AS Altri, Tabella2.YEAR, Tabella2.month FROM (SELECT SUM(CASE GET.Abbreviation WHEN '20DV' THEN 1 ELSE 0 END) AS DC20, SUM(CASE GET.Abbreviation WHEN '20OT' THEN 1 ELSE 0 END) AS OT20, SUM(CASE GET.Abbreviation WHEN '20FL' THEN 1 ELSE 0 END) AS FR20, SUM(CASE GET.Abbreviation WHEN '20RE' THEN 1 ELSE 0 END) AS RF20, SUM(CASE GET.Abbreviation WHEN '40DV' THEN 1 ELSE 0 END) AS DC40, SUM(CASE GET.Abbreviation WHEN '40OT' THEN 1 ELSE 0 END) AS OT40, SUM(CASE GET.Abbreviation WHEN '40FL' THEN 1 ELSE 0 END) AS FR40, SUM(CASE GET.Abbreviation WHEN '40HR' THEN 1 ELSE 0 END) AS RH40, SUM(CASE GET.Abbreviation WHEN '40HC' THEN 1 ELSE 0 END) AS HC40, SUM(CASE GET.Abbreviation WHEN '40HP' THEN 1 ELSE 0 END) AS HP40, SUM(CASE GET.Abbreviation WHEN '45HC' THEN 1 ELSE 0 END) AS HC45, SUM(CASE GET.Abbreviation WHEN '45HP' THEN 1 ELSE 0 END) AS HP45, SUM(CASE WHEN GET.Abbreviation != '20DV' AND GET.Abbreviation != '20OT' AND GET.Abbreviation != '20FL' AND GET.Abbreviation != '20RE' AND GET.Abbreviation != '40DV' AND GET.Abbreviation != '40OT' AND GET.Abbreviation != '40FL' AND GET.Abbreviation != '40HR' AND GET.Abbreviation != '40HC' AND GET.Abbreviation != '40HP' AND GET.Abbreviation != '45HC' AND GET.Abbreviation != '45HP' THEN 1 ELSE 0 END) AS Altri, GV.Vessel_Name, GVPC.Import_Documentation_Voyage_Number, GVPC.Actual_Arrival_Time, DATEPART(MONTH, GVPC.Actual_Arrival_Time) AS month, DATEPART(YEAR, GVPC.Actual_Arrival_Time) AS YEAR FROM [My_DB].[dbo].[GISEquipment] GE, [Interlink_Main90].[dbo].[GISEquipment_Type] GET, [Interlink_Main90].[dbo].[Equipment_Cycle] EC, [Interlink_Main90].[dbo].[Equipment_Cycle_Type] ECT, [Interlink_Main90].[dbo].[Equipment_Event] EE, [Interlink_Main90].[dbo].[Equipment_Event_Type] EET, [Interlink_Main90].[dbo].[GISLocation] GL, [Interlink_Main90].[dbo].[GISPort] GP, [Interlink_Main90].[dbo].[GISVoyage] GV, [Interlink_Main90].[dbo].GISVoyage_Port_Call GVPC, [Interlink_Main90].[dbo].GISVessel GVE WHERE GE.Equipment_Type_id = GET.Equipment_Type_id AND GE.Equipment_id = EC.Equipment_id AND EC.Eq_Cycle_Type_id = ECT.Eq_Cycle_Type_id AND EC.Eq_Cycle_id = EE.EQ_Cycle_id AND EE.EQEV_Type_id = EET.EqEv_Type_id AND EE.Location_id = GL.Location_id AND EC.POD_id = GP.Port_id AND EET.Name IN ('IDV') AND GL.Global_Name = 'Leghorn' AND GP.Global_Name = 'Leghorn' AND EE.[Logical_Cancel] = '0' AND GVPC.Voyage_Port_Call_id = EC.Voyage_Port_Call_id AND GV.Vessel_id = GVE.Vessel_id AND GVPC.Voyage_id = GV.Voyage_id AND GVPC.Port_id = GP.Port_id AND GV.Logical_Cancel_Value = 0 AND GVPC.Logical_Cancel_Value = 0 AND GVE.Logical_Cancel_Value = 0 AND GVPC.Import_Documentation_Voyage_Number IS NOT NULL AND GVPC.Actual_Arrival_Time IS NOT NULL GROUP BY GV.Vessel_Name, GVPC.Import_Documentation_Voyage_Number, GVPC.Actual_Arrival_Time) Tabella2 WHERE YEAR = '2022' GROUP BY Tabella2.YEAR, Tabella2.month ORDER BY YEAR DESC, month; SET DATEFIRST 7; Thanks in advance for the help.
sql sub queries aggregation
I have a fairly complicated multiple nested query set that I need to aggregate in to one view but I keep getting a metric does not exist error. Each component piece runs fine but when I bring them all together I get and error that states Invalid operation: function sum(numeric, numeric, numeric) does not exist Any help would be greatly appreciated with LM_DSP as (Select metrics.reportingdate --,to_char(dateadd(DAY,1,reportingdate), 'IYYY-IW') as reporting_week ,metrics.location_allocated ,metrics.country_code ,nvl(sm.sub_region,'undesignated') as director ,nvl(sm.area,'undesignated') as region ,metrics.route_type ,sum(case when metrics_id = 1 then value else 0 end) as Delivered_Shipments ,sum(case when metrics_id =5 then value else 0 end) as LM_hours ,sum(case when metrics_id = 6 then value else 0 end) as LM_routes --DSP and _DA routes only ,sum(case when metrics_id in ('8','9','10','11','46','12','13','14','15','16','17','18','43','44','45') then value else 0 end) as LM_cost ,sum(case when metrics_id = 8 then value else 0 end ) as LM_base_cost_dsp ,sum(case when metrics_id = 9 then value else 0 end ) as LM_branding_cost_dsp ,sum(case when metrics_id = 10 then value else 0 end ) as LM_parking_cost_dsp ,sum(case when metrics_id = 11 then value else 0 end ) as LM_fuel_cost_dsp ,sum(case when metrics_id = 46 then value else 0 end ) as LM_fuel_card_cost_dsp ,sum(case when metrics_id = 12 then value else 0 end ) as LM_dispatcher_cost_dsp ,sum(case when metrics_id = 13 then value else 0 end ) as LM_tech_cost_dsp ,sum(case when metrics_id = 14 then value else 0 end ) as LM_deprecation_cost_dsp ,sum(case when metrics_id = 15 then value else 0 end ) as LM_undesignated_cost_dsp ,sum(case when metrics_id = 16 then value else 0 end ) as LM_inperiod_offmanifest_cost_dsp ,sum(case when metrics_id = 17 then value else 0 end ) as LM_outperiod_offmanifest_cost_dsp ,sum(case when metrics_id = 18 then value else 0 end ) as LM_outperiod_manifest_cost_dsp ,sum(case when metrics_id = 43 then value else 0 end ) as LM_monthly_fixed_fee_cost_dsp ,sum(case when metrics_id = 44 then value else 0 end ) as LM_variable_per_piece_cost_dsp ,sum(case when metrics_id = 45 then value else 0 end ) as LM_variable_branding_per_piece_cost_dsp from _finance.master_metrics_v2 metrics left join _bi_ddl.o_comp_stations_master sm on metrics.location_allocated = sm.station_code and SM.STATUS IN ('A', 'H') and sm.country_code in ('US','CA') and provider_type not in ('_DA') where --reportingdate >= '2017-12-31 00:00:00' reportingdate>='2019-01-06' and reportingdate <='2019-01-13' and provider_type = 'DSP' group by reportingdate ,metrics.location_allocated ,metrics.country_code ,provider_type ,metrics.route_type ,director ,region ), LM_ADA as (Select metrics.reportingdate --,to_char(dateadd(DAY,1,reportingdate), 'IYYY-IW') as reporting_week ,metrics.location_allocated ,metrics.country_code ,nvl(sm.sub_region,'undesignated') as director ,nvl(sm.area,'undesignated') as region ,metrics.route_type ,sum(case when metrics_id = 1 then value else 0 end) as Delivered_Shipments ,sum(case when metrics_id =48 then value else 0 end) as LM_hours ,sum(case when metrics_id = 49 then value else 0 end) as LM_routes ,sum(case when metrics_id in ('8','9','10','11','46','12','13','14','15','16','17','18','43','44','45') then value else 0 end) as LM_cost from _finance.master_metrics_v2 metrics left join _bi_ddl.o_comp_stations_master sm on metrics.location_allocated = sm.station_code and SM.STATUS IN ('A', 'H') and sm.country_code in ('US','CA') and provider_type = '_DA' where --reportingdate >= '2017-12-31 00:00:00' reportingdate>='2019-01-06' and reportingdate <='2019-01-13' group by reportingdate ,metrics.location_allocated ,metrics.country_code ,provider_type ,metrics.route_type ,director ,region ), LM_f as (Select metrics.reportingdate --to_char(dateadd(DAY,1,reportingdate), 'IYYY-IW') as reporting_week ,metrics.location_allocated ,metrics.country_code ,nvl(sm.sub_region,'undesignated') as director ,nvl(sm.area,'undesignated') as region ,metrics.route_type ,sum(case when metrics_id = 97 then value else 0 end) as Delivered_Shipments ,sum(case when metrics_id =98 then value else 0 end) as LM_hours --,sum(case when metrics_id = 6 then 0 else 0 end) as LM_routes --DSP and _DA routes only ,sum(case when metrics_id in (99,100) then value else 0 end) as LM_cost from _finance.master_metrics_v2 metrics left join _bi_ddl.o_comp_stations_master sm on metrics.location_allocated = sm.station_code and SM.STATUS IN ('A', 'H') and sm.country_code in ('US','CA') where --reportingdate >= '2017-12-31 00:00:00' reportingdate>='2019-01-06' and reportingdate <='2019-01-13' and provider_type = 'af' group by reportingdate ,metrics.location_allocated ,metrics.country_code ,provider_type ,metrics.route_type ,director ,region ) select LM_DSP.reportingdate ,LM_DSP.location_allocated ,LM_DSP.country_code ,LM_DSP.route_type ,LM_DSP.director ,LM_DSP.region ,sum(LM_DSP.Delivered_Shipments, LM_DA.Delivered_Shipments, LM_f.Delivered_Shipments) as Delivered_Shipments ,sum(LM_DSP.LM_hours,LM_DA.LM_hours,LM_f.LM_hours) as LM_hours ,sum(LM_DSP.LM_routes,LM_DA.LM_routes,LM_f.LM_routes) as LM_routes ,sum(LM_DSP.LM_cost,LM_DA.LM_cost,LM_f.LM_cost) as LM_cost ,LM_DSP.LM_base_cost_dsp ,LM_DSP.LM_branding_cost_dsp ,LM_DSP.LM_parking_cost_dsp ,LM_DSP.LM_fuel_cost_dsp ,LM_DSP.LM_fuel_card_cost_dsp ,LM_DSP.LM_dispatcher_cost_dsp ,LM_DSP.LM_tech_cost_dsp ,LM_DSP.LM_deprecation_cost_dsp ,LM_DSP.LM_undesignated_cost_dsp ,LM_DSP.LM_inperiod_offmanifest_cost_dsp ,LM_DSP.LM_outperiod_offmanifest_cost_dsp ,LM_DSP.LM_outperiod_manifest_cost_dsp ,LM_DSP.LM_monthly_fixed_fee_cost_dsp ,LM_DSP.LM_variable_per_piece_cost_dsp ,LM_DSP.LM_variable_branding_per_piece_cost_dsp from LM_DSP left join LM_DA on LM_DSP.reportingdate = LM_DA.reportingdate and LM_DSP.country_code = LM_DA.country_code and LM_DSP.location_allocated = LM_DA.location_allocated and LM_DSP.route_type = LM_DA.route_type left join LM_f on LM_DSP.reportingdate = LM_f.reportingdate and LM_DSP.country_code = LM_f.country_code and LM_DSP.location_allocated = LM_f.location_allocated and LM_DSP.route_type = LM_f.route_type
As the error message tells you, there is no function sum(numeric, numeric, numeric). sum() sums an expression over all rows of a group in an aggregation. Simply use +, when you want to add values across a row. For example change sum(LM_DSP.Delivered_Shipments, LM_DA.Delivered_Shipments, LM_f.Delivered_Shipments) as Delivered_Shipments to: LM_DSP.Delivered_Shipments + LM_DA.Delivered_Shipments + LM_f.Delivered_Shipments as Delivered_Shipments ... and all the others analogously.
Need Multiple Values from Single Column
I am trying to join these two tables, or use a sub-query to achieve the results I need. As of now I have the first query pulling hourly totals with a overall total between MIN(time) and MAX(time). I need to join the second query to get the total scans from MIN(time) and MAX(time) Any ideas of where I could be going wrong? select UPPER(t.operator) as Operator, CASE WHEN t.eventtype = 'Replenishment Complete' THEN (SUM(CASE WHEN DATEPART(HOUR,t.time) = 6 THEN 1 ELSE 0 END)) ELSE NULL END AS '6AM', CASE WHEN t.eventtype = 'Replenishment Complete' THEN (SUM(CASE WHEN DATEPART(HOUR,t.time) = 7 THEN 1 ELSE 0 END)) ELSE NULL END AS '7AM', CASE WHEN t.eventtype = 'Replenishment Complete' THEN (SUM(CASE WHEN DATEPART(HOUR,t.time) = 8 THEN 1 ELSE 0 END)) ELSE NULL END AS '8AM', CASE WHEN t.eventtype = 'Replenishment Complete' THEN (SUM(CASE WHEN DATEPART(HOUR,t.time) = 9 THEN 1 ELSE 0 END)) ELSE NULL END AS '9AM', CASE WHEN t.eventtype = 'Replenishment Complete' THEN (SUM(CASE WHEN DATEPART(HOUR,t.time) = 10 THEN 1 ELSE 0 END)) ELSE NULL END AS '10AM', CASE WHEN t.eventtype = 'Replenishment Complete' THEN (SUM(CASE WHEN DATEPART(HOUR,t.time) = 11 THEN 1 ELSE 0 END)) ELSE NULL END AS '11AM', CASE WHEN t.eventtype = 'Replenishment Complete' THEN (SUM(CASE WHEN DATEPART(HOUR,t.time) = 12 THEN 1 ELSE 0 END)) ELSE NULL END AS '12PM', CASE WHEN t.eventtype = 'Replenishment Complete' THEN (SUM(CASE WHEN DATEPART(HOUR,t.time) = 13 THEN 1 ELSE 0 END)) ELSE NULL END AS '1PM', CASE WHEN t.eventtype = 'Replenishment Complete' THEN (SUM(CASE WHEN DATEPART(HOUR,t.time) = 14 THEN 1 ELSE 0 END)) ELSE NULL END AS '2PM', CASE WHEN t.eventtype = 'Replenishment Complete' THEN (SUM(CASE WHEN DATEPART(HOUR,t.time) = 15 THEN 1 ELSE 0 END)) ELSE NULL END AS '3PM', CASE WHEN t.eventtype = 'Replenishment Complete' THEN (SUM(CASE WHEN DATEPART(HOUR,t.time) = 16 THEN 1 ELSE 0 END)) ELSE NULL END AS '4PM', CASE WHEN t.eventtype = 'Replenishment Complete' THEN (SUM(CASE WHEN DATEPART(HOUR,t.time) = 17 THEN 1 ELSE 0 END)) ELSE NULL END AS '5PM', CASE WHEN t.eventtype = 'Replenishment Complete' THEN (COUNT(CASE WHEN DATEPART(HOUR,t.time) > 17 THEN t.eventtype ELSE NULL END)) ELSE NULL END AS '6+PM', SUM(CASE WHEN t.eventtype = 'Replenishment Complete' THEN 1 ELSE 0 END) as TotalCanisters from mck_hvs.replevent t where CAST(t.time as DATE) = CAST(GETDATE() as DATE) and t.stationtype IN ('T', 'S') and t.eventtype = 'Replenishment Complete' group by t.operator, t.eventtype Second query: select UPPER(o.operator) as Operator, SUM(CASE WHEN o.eventtype = 'GoodScan' THEN 1 ELSE 0 END) as TotalScans, convert( varchar(19), MIN(o.time), 8) as LogonTime, DATEDIFF(MINUTE, MIN(o.time), MAX(o.time)) as TotalMinLogon from mck_hvs.replevent o where CAST(o.time as DATE) = CAST(GETDATE() as DATE) and o.eventtype IN ( 'Replenishment Complete', 'GoodScan' ) group by o.operator order by o.operator
Something like the below should get you headed to a solution. I removed the group on t.eventtype and removed from the case statements because the where clause already limited the results for you. select op.Operator, op.TotalScans, op.LogonTime, op.TotalMinLogon, b.[6AM], b.[7AM], b.[8AM], b.[9AM], b.[10AM], b.[11AM], b.[12PM], b.[1PM], b.[2PM], b.[3PM], b.[4PM], b.[5PM], b.[6+PM] from ( select UPPER(o.operator) as Operator, SUM(CASE WHEN o.eventtype = 'GoodScan' THEN 1 ELSE 0 END) as TotalScans, convert( varchar(19), MIN(o.time), 8) as LogonTime, DATEDIFF(MINUTE, MIN(o.time), MAX(o.time)) as TotalMinLogon from mck_hvs.replevent o where --will use o.time index now: o.time >= CAST(GETDATE() as DATE) and o.time < CAST(dateadd(Day,1,GETDATE()) as DATE) and o.eventtype IN ( 'Replenishment Complete', 'GoodScan' ) group by o.operator ) as op left join ( select UPPER(t.operator) as Operator, SUM(CASE WHEN DATEPART(HOUR,t.time) = 6 THEN 1 ELSE 0 END) AS '6AM', SUM(CASE WHEN DATEPART(HOUR,t.time) = 7 THEN 1 ELSE 0 END) AS '7AM', SUM(CASE WHEN DATEPART(HOUR,t.time) = 8 THEN 1 ELSE 0 END) AS '8AM', SUM(CASE WHEN DATEPART(HOUR,t.time) = 9 THEN 1 ELSE 0 END) AS '9AM', SUM(CASE WHEN DATEPART(HOUR,t.time) = 10 THEN 1 ELSE 0 END) AS '10AM', SUM(CASE WHEN DATEPART(HOUR,t.time) = 11 THEN 1 ELSE 0 END) AS '11AM', SUM(CASE WHEN DATEPART(HOUR,t.time) = 12 THEN 1 ELSE 0 END) AS '12PM', SUM(CASE WHEN DATEPART(HOUR,t.time) = 13 THEN 1 ELSE 0 END) AS '1PM', SUM(CASE WHEN DATEPART(HOUR,t.time) = 14 THEN 1 ELSE 0 END) AS '2PM', SUM(CASE WHEN DATEPART(HOUR,t.time) = 15 THEN 1 ELSE 0 END) AS '3PM', SUM(CASE WHEN DATEPART(HOUR,t.time) = 16 THEN 1 ELSE 0 END) AS '4PM', SUM(CASE WHEN DATEPART(HOUR,t.time) = 17 THEN 1 ELSE 0 END) AS '5PM', SUM(CASE WHEN DATEPART(HOUR,t.time) > 17 THEN 1 ELSE 0 END) AS '6+PM', SUM(CASE WHEN t.eventtype = 'Replenishment Complete' THEN 1 ELSE 0 END) as TotalCanisters from mck_hvs.replevent t where --will use o.time index now: o.time >= CAST(GETDATE() as DATE) and o.time < CAST(dateadd(Day,1,GETDATE()) as DATE) and t.stationtype IN ('T', 'S') and t.eventtype = 'Replenishment Complete' group by t.operator ) as b on b.Operator = op.Operator
SELECT l.* , r.TotalScans , r.LogonTime , r.TotalMinLogon FROM ( SELECT UPPER(t.operator) AS Operator , CASE WHEN t.eventtype = 'Replenishment Complete' THEN ( SUM(CASE WHEN DATEPART(HOUR, t.time) = 6 THEN 1 ELSE 0 END) ) ELSE NULL END AS '6AM' , CASE WHEN t.eventtype = 'Replenishment Complete' THEN ( SUM(CASE WHEN DATEPART(HOUR, t.time) = 7 THEN 1 ELSE 0 END) ) ELSE NULL END AS '7AM' , CASE WHEN t.eventtype = 'Replenishment Complete' THEN ( SUM(CASE WHEN DATEPART(HOUR, t.time) = 8 THEN 1 ELSE 0 END) ) ELSE NULL END AS '8AM' , CASE WHEN t.eventtype = 'Replenishment Complete' THEN ( SUM(CASE WHEN DATEPART(HOUR, t.time) = 9 THEN 1 ELSE 0 END) ) ELSE NULL END AS '9AM' , CASE WHEN t.eventtype = 'Replenishment Complete' THEN ( SUM(CASE WHEN DATEPART(HOUR, t.time) = 10 THEN 1 ELSE 0 END) ) ELSE NULL END AS '10AM' , CASE WHEN t.eventtype = 'Replenishment Complete' THEN ( SUM(CASE WHEN DATEPART(HOUR, t.time) = 11 THEN 1 ELSE 0 END) ) ELSE NULL END AS '11AM' , CASE WHEN t.eventtype = 'Replenishment Complete' THEN ( SUM(CASE WHEN DATEPART(HOUR, t.time) = 12 THEN 1 ELSE 0 END) ) ELSE NULL END AS '12PM' , CASE WHEN t.eventtype = 'Replenishment Complete' THEN ( SUM(CASE WHEN DATEPART(HOUR, t.time) = 13 THEN 1 ELSE 0 END) ) ELSE NULL END AS '1PM' , CASE WHEN t.eventtype = 'Replenishment Complete' THEN ( SUM(CASE WHEN DATEPART(HOUR, t.time) = 14 THEN 1 ELSE 0 END) ) ELSE NULL END AS '2PM' , CASE WHEN t.eventtype = 'Replenishment Complete' THEN ( SUM(CASE WHEN DATEPART(HOUR, t.time) = 15 THEN 1 ELSE 0 END) ) ELSE NULL END AS '3PM' , CASE WHEN t.eventtype = 'Replenishment Complete' THEN ( SUM(CASE WHEN DATEPART(HOUR, t.time) = 16 THEN 1 ELSE 0 END) ) ELSE NULL END AS '4PM' , CASE WHEN t.eventtype = 'Replenishment Complete' THEN ( SUM(CASE WHEN DATEPART(HOUR, t.time) = 17 THEN 1 ELSE 0 END) ) ELSE NULL END AS '5PM' , CASE WHEN t.eventtype = 'Replenishment Complete' THEN ( COUNT(CASE WHEN DATEPART(HOUR, t.time) > 17 THEN t.eventtype ELSE NULL END) ) ELSE NULL END AS '6+PM' , SUM(CASE WHEN t.eventtype = 'Replenishment Complete' THEN 1 ELSE 0 END) AS TotalCanisters FROM #replevent t WHERE CAST(t.time AS DATE) = CAST(GETDATE() AS DATE) AND t.stationtype IN ( 'T', 'S' ) AND t.eventtype = 'Replenishment Complete' GROUP BY t.operator , t.eventtype ) AS l INNER JOIN ( SELECT UPPER(o.operator) AS Operator_r , SUM(CASE WHEN o.eventtype = 'GoodScan' THEN 1 ELSE 0 END) AS TotalScans , CONVERT(VARCHAR(19), MIN(o.time), 8) AS LogonTime , DATEDIFF(SECOND, MIN(o.time), MAX(o.time)) AS TotalMinLogon FROM #replevent o WHERE CAST(o.time AS DATE) = CAST(GETDATE() AS DATE) AND o.eventtype IN ( 'Replenishment Complete', 'GoodScan' ) GROUP BY o.operator ) AS r ON l.Operator = r.Operator_r ORDER BY l.Operator;
I Need to get a count of activities by month grouped by a Department
I am trying to get a count of activities by month and group them by a department name. The report is based on a date parameter that I input to the query "#rptDate". What I have below works, but I'm guessing there is a better way of doing the same thing and hoping someone can shed some light. Select Count(*) As Month1Count, 0 As Month2Count, 0 As Month3Count, 0 As Month4Count, 0 as Month5Count, 0 as Month6Count, 0 as Month7Count, 0 as Month8Count, 0 as Month9COunt, 0 as Month10Count, 0 as Month11Count, 0 as Month12Count, DepartmentName,ActivityDescription from reports.WorkOrders WHERE Month(BeginDate) = Month(#rptDate) and Year(BeginDate) = Year(#rptDate) Group By DepartmentName, ActivityDescription UNION Select 0 As Month1Count, COUNT(*) As Month2Count, 0 as Month3Count, 0 as Month4Count, 0 as Month5Count, 0 as Month6Count, 0 as Month7Count, 0 as Month8Count, 0 as Month9COunt, 0 as Month10Count, 0 as Month11Count, 0 as Month12Count, DepartmentName,ActivityDescription from reports.WorkOrders WHERE Month(BeginDate) = Month(#rptDate) + 1 and Year(BeginDate) = Year(DateAdd(month,1,#rptDate)) Group By DepartmentName, ActivityDescription UNION Select 0 As Month1Count, 0 As Month2Count, Count(*) as Month3Count, 0 as Month4Count, 0 as Month5Count, 0 as Month6Count, 0 as Month7Count, 0 as Month8Count, 0 as Month9COunt, 0 as Month10Count, 0 as Month11Count, 0 as Month12Count, DepartmentName, ActivityDescription from reports.WorkOrders WHERE Month(BeginDate) = Month(#rptDate) + 2 and Year(BeginDate) = Year(DateAdd(month,2,#rptDate)) Group By DepartmentName, ActivityDescription
I haven't tested the following, so it's possible there are some typos or minor errors, but I think the following is what you want: SELECT sum(case when Month(BeginDate) = Month(dateadd(month, 0, #rptDate)) then 1 else 0 end) as Month1Count, sum(case when Month(BeginDate) = Month(dateadd(month, 1, #rptDate)) then 1 else 0 end) as Month2Count, sum(case when Month(BeginDate) = Month(dateadd(month, 2, #rptDate)) then 1 else 0 end) as Month3Count, sum(case when Month(BeginDate) = Month(dateadd(month, 3, #rptDate)) then 1 else 0 end) as Month4Count, sum(case when Month(BeginDate) = Month(dateadd(month, 4, #rptDate)) then 1 else 0 end) as Month5Count, sum(case when Month(BeginDate) = Month(dateadd(month, 5, #rptDate)) then 1 else 0 end) as Month6Count, sum(case when Month(BeginDate) = Month(dateadd(month, 6, #rptDate)) then 1 else 0 end) as Month7Count, sum(case when Month(BeginDate) = Month(dateadd(month, 7, #rptDate)) then 1 else 0 end) as Month8Count, sum(case when Month(BeginDate) = Month(dateadd(month, 8, #rptDate)) then 1 else 0 end) as Month9Count, sum(case when Month(BeginDate) = Month(dateadd(month, 9, #rptDate)) then 1 else 0 end) as Month10Count, sum(case when Month(BeginDate) = Month(dateadd(month, 10, #rptDate)) then 1 else 0 end) as Month11Count, sum(case when Month(BeginDate) = Month(dateadd(month, 11, #rptDate)) then 1 else 0 end) as Month12Count DepartmentName, ActivityDescription FROM reports.WorkOrders WHERE Year(BeginDate) + right('0'+Month(BeginDate),2) between Year(#rptDate) + right('0'+Month(#rptDate),2) and Year(dateadd(month,11,#rptDate)) + right('0'+Month(dateadd(month,11,#rptDate)),2) GROUP BY DepartmentName, ActivityDescription Do let me know how you get on with this. If I've made typos and you can't correct for them, do report the error message and/or any problems with the results.
Duplicate rows in SQL statement
the below SQL statement generates a pivot table, all of which is working correctly. However, at the bottom of the code, I am trying to display values from another table (availabilitynotes) - in this example below the note would be "A/P". Each single day will have either 0 or 1 notes on the individual day. When a note is present, the note is displayed. When no note is present, the COALESCE value is displayed. However, when a note for 1 teacher is set on a monday and one on a wednesday, a duplicate row is returned. How can I set it to return all values on one single row? WITH Bookings AS ( SELECT TeacherID, [WeekDay] = DATENAME(WEEKDAY, BookingDate), [Status] = CASE WHEN [2] > 0 THEN 'XXX' WHEN [0] > 0 AND [1] > 0 THEN 'XXX' WHEN [0] > 0 THEN 'PM' WHEN [1] > 0 THEN 'AM' WHEN [3] > 0 AND CONVERT(time(0), EndTime) <= CONVERT(time(0), '12:00:00') and CONVERT(time(0), StartTime) < CONVERT(time(0), '12:00:00') THEN 'PM' WHEN [3] > 0 AND CONVERT(time(0), StartTime) >= CONVERT(time(0), '12:00:00') THEN 'AM' WHEN [3] > 0 AND CONVERT(time(0), StartTime) <= CONVERT(time(0), '12:00:00') AND CONVERT(time(0), EndTime) >= CONVERT(time(0), '12:00:00') THEN 'XXX' END FROM ( SELECT TeacherID, BookingDate, BookingDuration, StartTime, EndTime, [X] = 1 FROM BookingDays where (Status = 0 or Status IS NULL) ) BookingDays PIVOT ( SUM(X) FOR BookingDuration IN ([0], [1], [2], [3]) ) pvt WHERE BookingDate >= DATEADD(ww, DATEDIFF(ww,0,#Date), 0) AND BookingDate <= DATEADD(ww, DATEDIFF(ww,0,#Date), 6) ), PivotedBookings AS ( SELECT * FROM Bookings PIVOT ( MAX([Status]) FOR [WeekDay] IN ([Monday], [Tuesday], [Wednesday], [Thursday], [Friday]) ) pvt ) SELECT t.ID, t.Firstname, t.Surname, CASE WHEN t.Nursery > 0 THEN 'NUR' WHEN t.Reception > 0 THEN 'REC' WHEN t.Year1 > 0 THEN 'Y1' WHEN t.Year2 > 0 THEN 'Y2' WHEN t.Year3 > 0 THEN 'Y3' WHEN t.Year4 > 0 THEN 'Y4' WHEN t.Year5 > 0 THEN 'Y5' WHEN t.Year6 > 0 THEN 'Y6' WHEN t.Year7 > 0 THEN 'Y7' WHEN t.Year8 > 0 THEN 'Y8' WHEN t.Year9 > 0 THEN 'Y9' WHEN t.Year10 > 0 THEN 'Y10' WHEN t.Year11 > 0 THEN 'Y11' WHEN t.ALevel > 0 THEN 'ALevel' END + ' - ' + CASE WHEN t.ALevel > 0 THEN 'ALevel' WHEN t.Year11 > 0 THEN 'Y11' WHEN t.Year10 > 0 THEN 'Y10' WHEN t.Year9 > 0 THEN 'Y9' WHEN t.Year8 > 0 THEN 'Y7' WHEN t.Year6 > 0 THEN 'Y6' WHEN t.Year5 > 0 THEN 'Y6' WHEN t.Year4 > 0 THEN 'Y4' WHEN t.Year3 > 0 THEN 'Y3' WHEN t.Year2 > 0 THEN 'Y2' WHEN t.Year1 > 0 THEN 'Y1' WHEN t.Reception > 0 THEN 'REC' WHEN t.Nursery > 0 THEN 'NUR' ELSE '' END as 'KeyStage', Monday = CASE WHEN an.Date = DATEADD(ww, DATEDIFF(ww,0,#Date), 0) AND an.TeacherID = t.ID THEN an.Text WHEN t.Status = 0 THEN 'XXX' ELSE COALESCE(pb.Monday, '') END, Tuesday = CASE WHEN an.Date = DATEADD(ww, DATEDIFF(ww,0,#Date), 1) AND an.TeacherID = t.ID THEN an.Text WHEN t.Status = 0 THEN 'XXX' ELSE COALESCE(pb.Tuesday, '') END, Wednesday = CASE WHEN an.Date = DATEADD(ww, DATEDIFF(ww,0,#Date), 2) AND an.TeacherID = t.ID THEN an.Text WHEN t.Status = 0 THEN 'XXX' ELSE COALESCE(pb.Wednesday, '') END, Thursday = CASE WHEN an.Date = DATEADD(ww, DATEDIFF(ww,0,#Date), 3) AND an.TeacherID = t.ID THEN an.Text WHEN t.Status = 0 THEN 'XXX' ELSE COALESCE(pb.Thursday, '') END, Friday = CASE WHEN an.Date = DATEADD(ww, DATEDIFF(ww,0,#Date), 4) AND an.TeacherID = t.ID THEN an.Text WHEN t.Status = 0 THEN 'XXX' ELSE COALESCE(pb.Friday, '') END FROM Teachers t LEFT JOIN PivotedBookings pb ON pb.TeacherID = t.ID LEFT JOIN TeacherBands tb ON tb.ID = t.Band LEFT JOIN AvailabilityNotes an ON t.ID = an.TeacherID WHERE t.Active = 0 and (t.Status = 1 or t.Status = 0) and t.PrimarySchool = 1 ORDER BY t.Surname, t.Firstname asc This generates the following output - ID | Firstname | Surname | Mon | Tue | Wed | Thu | Fri 1 Steve Smith XXX PM AM A/P NULL 1 Steve Smith XXX PM AM NULL A/P When I need it to be - ID | Firstname | Surname | Mon | Tue | Wed | Thu | Fri 1 Steve Smith XXX PM AM A/P A/P Thanks
You need the valid value for each day, which will be greater than NULL if extant. select ID, Firstname, Surname , max(Monday) as Monday, -- etc from ( your giant query ) as Q group by ID, Firstname, Surname should do the trick.