SVK
SVK

Reputation: 1034

Return SQL Server column name and corresponding value based on column value

How do I return column name and value based on column value for each record ?

I have this: I have this

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 want this

I got till this point, using cross apply.

enter image description here

Upvotes: 1

Views: 80

Answers (2)

John Cappelletti
John Cappelletti

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

John Cappelletti
John Cappelletti

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

Related Questions