I’ve been away for sometime and need help with, what is probably a simple solution but at this time I’m stuck. I have this select statement and need to combine rows with like elements for the same department but the group by would have a very large select list, is there another way like MERGE? Here is the sql stmt I’m dealing with along with the output:
SELECT distinct sg.Description as 'Groups', si.Store_Name, a.Store_ID, si.Store_ID1 as 'Store #2', d.Department_ID as 'Dept', a.Vendor_ID,
IIF(d.Delivery_Day = 1, dbo.DayOfWeekToString(d.Order_Day),null) as 'Sun',
IIF(d.Delivery_Day = 1, CONCAT(CONVERT(varchar, d.Deadline_Hour) , ':', RIGHT('00' + CONVERT(varchar, d.Deadline_Minute), 2)) ,null ) as 'time',
IIF(d.Delivery_Day = 2, dbo.DayOfWeekToString(d.Order_Day),null) as 'Mon',
IIF(d.Delivery_Day = 2, CONCAT(CONVERT(varchar, d.Deadline_Hour) , ':', RIGHT('00' + CONVERT(varchar, d.Deadline_Minute), 2)) ,null ) as 'time',
IIF(d.Delivery_Day = 3, dbo.DayOfWeekToString(d.Order_Day),null) as 'Tue',
IIF(d.Delivery_Day = 3, CONCAT(CONVERT(varchar, d.Deadline_Hour) , ':', RIGHT('00' + CONVERT(varchar, d.Deadline_Minute), 2)) ,null ) as 'time',
IIF(d.Delivery_Day = 4, dbo.DayOfWeekToString(d.Order_Day),null) as 'Wed',
IIF(d.Delivery_Day = 4, CONCAT(CONVERT(varchar, d.Deadline_Hour) , ':', RIGHT('00' + CONVERT(varchar, d.Deadline_Minute), 2)) ,null ) as 'time',
IIF(d.Delivery_Day = 5, dbo.DayOfWeekToString(d.Order_Day),null) as 'Thu',
IIF(d.Delivery_Day = 5, CONCAT(CONVERT(varchar, d.Deadline_Hour) , ':', RIGHT('00' + CONVERT(varchar, d.Deadline_Minute), 2)) ,null ) as 'time',
IIF(d.Delivery_Day = 6, dbo.DayOfWeekToString(d.Order_Day),null) as 'Fri',
IIF(d.Delivery_Day = 6, CONCAT(CONVERT(varchar, d.Deadline_Hour) , ':', RIGHT('00' + CONVERT(varchar, d.Deadline_Minute), 2)) ,null ) as 'time',
IIF(d.Delivery_Day = 7, dbo.DayOfWeekToString(d.Order_Day),null) as 'Sat',
IIF(d.Delivery_Day = 7, CONCAT(CONVERT(varchar, d.Deadline_Hour) , ':', RIGHT('00' + CONVERT(varchar, d.Deadline_Minute), 2)),null) as 'time'
from Delivery_Schedule_Header a Join Vendor_Info b ON (a.Vendor_ID = b.Vendor_ID) Join Delivery_Schedule_Detail d on d.UID_Delivery = a.UID
Join Store_Info si on si.Store_ID = a.Store_ID Join Store_Group sg on sg.GroupStore_UID = si.GroupStore_UID
Where a.Vendor_ID = @Vendor_Id and si.GroupStore_UID = Case when @Group_Id = -1 then si.GroupStore_UID else @Group_Id end
and the results:
Groups Store_Name Store_ID Store #2 Dept Vendor_ID Sun time Mon time Tue time Wed time Thu time Fri time Sat time
Balls Price Chopper 18 18 18 3200 70038000 NULL NULL NULL NULL NULL NULL NULL NULL Wednesday 11:00 NULL NULL NULL NULL
Balls Price Chopper 18 18 18 3200 70038000 NULL NULL NULL NULL Monday 11:00 NULL NULL NULL NULL NULL NULL NULL NULL
Balls Price Chopper 18 18 18 3200 70038000 Saturday 11:00 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL
These three rows need to be combined under the same department sorry if this is rather elementary but I’ve been out of this type of work for sometime now and need a refresher. Thanks
Advertisement
Answer
You want conitional aggregation. This works by creating a group by
clause that contains all columns except those you want to merge, and then surround the conditional expression with an aggregate function (such as MIN()
or MAX()
:
SELECT
sg.Description as Groups,
si.Store_Name,
a.Store_ID,
si.Store_ID1 as Store_2,
d.Department_ID as Dept,
a.Vendor_ID,
MAX(CASE WHEN d.Delivery_Day = 1 THEN dbo.DayOfWeekToString(d.Order_Day) END) as Sun,
MAX(CASE
WHEN d.Delivery_Day = 1
THEN CONCAT(CONVERT(varchar, d.Deadline_Hour) , ':', RIGHT('00' + CONVERT(varchar, d.Deadline_Minute), 2))
) as Sun_time,
FROM Delivery_Schedule_Header a
JOIN Vendor_Info b ON a.Vendor_ID = b.Vendor_ID
JOIN Delivery_Schedule_Detail d ON d.UID_Delivery = a.UID
JOIN Store_Info si ON si.Store_ID = a.Store_ID
JOIN Store_Group sg ON sg.GroupStore_UID = si.GroupStore_UID
WHERE
a.Vendor_ID = @Vendor_Id
AND si.GroupStore_UID = CASE WHEN @Group_Id = -1 THEN si.GroupStore_UID ELSE @Group_Id END
GROUP BY
sg.Description as Groups,
si.Store_Name,
a.Store_ID,
si.Store_ID1 as Store_2,
d.Department_ID as Dept,
a.Vendor_ID
Side notes:
I rewrote the
IIF()
expressions to useCASE
(the latter is standard SQL, while the former is TSQL-specific)single quotes should be used for litteral strings, not for column identifiers (although SQL Server tolerates this)
you have multiple columns in the resultset that have the same name (
time
), this is not a good practice