|
|
Question : Combining multiple rows into a single column
|
|
I have table A with two columns
Location_ ID, ITEM_ID
1 location many items (min 1 , max 5 items per location)
In my report I want to concat all item_id delimited by ',' by each location
the output would be as follows:
Location ITEM
Westchester 12546,145879,15698,12583 Torrance 32145,3258,32458 Glendale 14785 Pasadena 14589,156478
Please advise with good sql code.
|
Answer : Combining multiple rows into a single column
|
|
OK, here we go. I've included the test tables and data you posted that I used. This is not the cleanest bit of code but ti's a starting point. Hope you can understand it. I've included 2 selects, one that concatinates, and one that keeps the fields separate. It's eisier to work with them separate for testing.
Create table location(locationID int, location varchar(50)) Create table item(itemID int, locationID int)
insert location(locationID, location) values(1, 'Westchester') insert location(locationID, location) values(2, 'Torrance') insert location(locationID, location) values(3, 'Glendale') insert location(locationID, location) values(4, 'Pasadena')
INSERT item(itemID, locationID) values(12546, 1) INSERT item(itemID, locationID) values(145879, 1) INSERT item(itemID, locationID) values(15698, 1) INSERT item(itemID, locationID) values(12583, 1) INSERT item(itemID, locationID) values(32145, 2) INSERT item(itemID, locationID) values(3258, 2) INSERT item(itemID, locationID) values(32458, 2) INSERT item(itemID, locationID) values(14785, 3) INSERT item(itemID, locationID) values(14589, 4) INSERT item(itemID, locationID) values(156478, 4)
Select l.location, i1.itemid, i2.itemid, i3.itemid, i4.itemid, i5.itemid, t1.citenid from location l inner join item i1 ON l.locationid = i1.locationid left outer join item i2 ON l.locationid = i2.locationid AND i1.itemid < i2.itemID left outer join item i3 ON l.locationid = i3.locationid AND i2.itemid < i3.itemID left outer join item i4 ON l.locationid = i4.locationid AND i3.itemid < i4.itemID left outer join item i5 ON l.locationid = i5.locationid AND i4.itemid < i5.itemID INNER JOIN (Select l.locationID, MIN(i1.itemid) itemid, count(*) as citenid from location l inner join item i1 ON l.locationid = i1.locationid GROUP BY l.locationID) t1 ON t1.locationid = l.locationid AND t1.itemid = i1.itemid WHERE CASE t1.citenid WHEN 1 THEN i1.itemid WHEN 2 THEN i2.itemid WHEN 3 THEN i3.itemid WHEN 4 THEN i4.itemid WHEN 5 THEN i5.itemid END is not null group by l.location, i1.itemid, i2.itemid, i3.itemid, i4.itemid, i5.itemid, t1.citenid order by 1
Select l.location, CONVERT(varchar, i1.itemid) + CASE WHEN i2.itemid is null THEN '' ELSE ', ' + CONVERT(varchar, i2.itemid) END + CASE WHEN i3.itemid is null THEN '' ELSE ', ' + CONVERT(varchar, i3.itemid) END + CASE WHEN i4.itemid is null THEN '' ELSE ', ' + CONVERT(varchar, i4.itemid) END + CASE WHEN i5.itemid is null THEN '' ELSE ', ' + CONVERT(varchar, i5.itemid) END as Item_List from location l inner join item i1 ON l.locationid = i1.locationid left outer join item i2 ON l.locationid = i2.locationid AND i1.itemid < i2.itemID left outer join item i3 ON l.locationid = i3.locationid AND i2.itemid < i3.itemID left outer join item i4 ON l.locationid = i4.locationid AND i3.itemid < i4.itemID left outer join item i5 ON l.locationid = i5.locationid AND i4.itemid < i5.itemID INNER JOIN (Select l.locationID, MIN(i1.itemid) itemid, count(*) as citenid from location l inner join item i1 ON l.locationid = i1.locationid GROUP BY l.locationID) t1 ON t1.locationid = l.locationid AND t1.itemid = i1.itemid WHERE CASE t1.citenid WHEN 1 THEN i1.itemid WHEN 2 THEN i2.itemid WHEN 3 THEN i3.itemid WHEN 4 THEN i4.itemid WHEN 5 THEN i5.itemid END is not null group by l.location, i1.itemid, i2.itemid, i3.itemid, i4.itemid, i5.itemid, t1.citenid order by 1
|
|
|
|
|