user896917
user896917

Reputation: 105

SQL Server merge multiple rows into one column

I'm trying to merge multiple rows into one column. I have a table:

COST_ID PRICE_ID PRICE_TIER   COST
1        4         1        850.00
2        4         2        950.00 
3        4         3        1000.00
4        7         1        250.00
5        7         2        275.00
6        7         3        300.00

And I want to the output one row for each price_id, it should look something like this:

ID PriceID C1ID C1Cost   C2ID  C2Cost C3ID  C3Cost
1    4      1    850.00    2   950.00   3    1000.00
2    7      4    250.00    5   275.00   6    300.00

Thank you for your help.

Upvotes: 3

Views: 3481

Answers (3)

GarethD
GarethD

Reputation: 69759

My preferred solution would be using a conditional aggregate like so:

SELECT  ROW_NUMBER() OVER(ORDER BY Price_ID) [ID],
        Price_ID,
        MIN(CASE WHEN Price_Tier = 1 THEN Cost_ID END) [C1ID],
        MIN(CASE WHEN Price_Tier = 1 THEN Cost    END) [C1Cost],
        MIN(CASE WHEN Price_Tier = 2 THEN Cost_ID END) [C2ID],
        MIN(CASE WHEN Price_Tier = 2 THEN Cost    END) [C2Cost],
        MIN(CASE WHEN Price_Tier = 3 THEN Cost_ID END) [C3ID],
        MIN(CASE WHEN Price_Tier = 3 THEN Cost    END) [C3Cost]
FROM    T
GROUP BY Price_ID

However this can also be done with SQL-Server's PIVOT function. However it requires a UNION because PIVOT does not allow for multiple aggregates in a single PIVOT.

SELECT  ROW_NUMBER() OVER(ORDER BY Price_ID) [ID],
        *
FROM    (   SELECT  Price_ID, 'C' + CONVERT(VARCHAR, Price_Tier) + 'Cost' [Price_Tier], MIN(Cost) [Value]
            FROM    T
            GROUP BY Price_ID, Price_Tier
            UNION ALL
            SELECT  Price_ID, 'C' + CONVERT(VARCHAR, Price_Tier) + 'ID' [Price_Tier], MIN(Cost_ID) [Value]
            FROM    T
            GROUP BY Price_ID, Price_Tier
        ) data
        PIVOT
        (   MAX(Value) 
            FOR Price_Tier IN ([C1ID], [C1Cost], [C2ID], [C2Cost], [C3ID], [C3Cost])
        ) Pvt

Demonstrative SQL Fiddle

Upvotes: 2

Tim Lehner
Tim Lehner

Reputation: 15251

If PRICE_ID and PRICE_TIER form a unique key, you can do something like this:

select
      row_number() over (order by PRICE_ID) as ID
    , PRICE_ID as PriceID
    , (select COST_ID from cte where PRICE_ID = t.PRICE_ID and PRICE_TIER = 1) as C1ID
    , (select COST from cte where PRICE_ID = t.PRICE_ID and PRICE_TIER = 1) as C1Cost
    , (select COST_ID from cte where PRICE_ID = t.PRICE_ID and PRICE_TIER = 2) as C2ID
    , (select COST from cte where PRICE_ID = t.PRICE_ID and PRICE_TIER = 2) as C2Cost
    , (select COST_ID from cte where PRICE_ID = t.PRICE_ID and PRICE_TIER = 3) as C3ID
    , (select COST from cte where PRICE_ID = t.PRICE_ID and PRICE_TIER = 3) as C3Cost
from MY_TABLE t
group by PRICE_ID
order by PRICE_ID

Upvotes: 0

Simon
Simon

Reputation: 6152

SQL Server has Pivot Tables, Pinal Dave usually provides a good introduction to SQL Server stuff - it's a place to start at least.

Upvotes: 0

Related Questions