Reputation: 1034
How do I return column name and value based on column value for each record ?
I would like to update
first_color with color name having highest value
first_value with highest value and so on, as shown in the below snippet.
Note: This is just an example, I have over 100 columns for which I need column name & value for top 5 columns/values. So, looking for a dynamic sql if possible.
I got till this point, using cross apply.
Upvotes: 1
Views: 80
Reputation: 81990
With new information, this will unpivot your data without having to to go dynamic. You can then PIVOT if desired
Select A.unique_id
,C.*
,ColNr = Row_Number() over (Partition By unique_id Order by Value Desc)
From YourTable A
Cross Apply ( values (cast((Select A.* for XML RAW) as xml))) B(XMLData)
Cross Apply (
Select Field = a.value('local-name(.)','varchar(100)')
,Value = a.value('.','varchar(max)')
From B.XMLData.nodes('/row') as C1(n)
Cross Apply C1.n.nodes('./@*') as C2(a)
Where a.value('local-name(.)','varchar(100)') not in ('unique_id')
) C
Returns
unique_id Field Value ColNr
abc12 Black 7 1
abc12 Blue 4 2
abc12 Green 2 3
abc12 Red 1 4
mnc23 Green 4 1
mnc23 Black 3 2
mnc23 Red 2 3
mnc23 Blue 1 4
Upvotes: 1
Reputation: 81990
SQL Server Approach
Perhaps with a CROSS APPLY in concert with a ROW_NUMBER()
Example
Select A.*
,B.*
from YourTable2 A
Cross Apply (Select First_Color = max(case when RN=1 then Item end)
,First_Value = max(case when RN=1 then Value end)
,Second_Color = max(case when RN=2 then Item end)
,Second_Value = max(case when RN=2 then Value end)
From (Select *,RN=Row_Number() over (Order by Value Desc)
From ( values ('Red',Red)
,('Green',Green)
,('Blue',Blue)
,('Black',Black)
) B1 (Item,Value)
) B2
) B
Returns
unique_id Red Green Blue Black First_Color First_Value Second_Color Second_Value
abc12 1 2 4 7 Black 7 Blue 4
mnc23 2 4 1 3 Green 4 Black 3
Upvotes: 2