Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQL query for fetching a single record in format "column heading: column value"

Suppose I have this table:

Create table test(a int, b int, c int, d int)

I can write simply 'select * from test' to get the following first record:

A    B    C    D  
1    2    3    4

But instead, I want it like this (Four rows for single record):

A: 1  
B: 2  
C: 3  
D: 4

Can someone help me in doing this?

This is required to view a single record on remote desktop system which is extremely slow, and horizontal scrolling on it sucks, and has 800 columns in it. So I need to see the format of data from a single record.

like image 928
teenup Avatar asked Dec 20 '22 12:12

teenup


1 Answers

You can use the UNPIVOT function to do this, the version below concatenates the column name and value together, but you can always display them as separate columns:

select col+':'+cast(value as varchar(10)) col
from test
unpivot
(
  value
  for col in (A, B, C, D)
) unpiv

See SQL Fiddle with Demo

The above works great if you have a known number of columns, but if you have 800 columns that you want to transform, you might want to use dynamic sql to perform this:

DECLARE @colsUnpivot AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @colsUnpivot = stuff((select ','+quotename(C.name)
         from sys.columns as C
         where C.object_id = object_id('test')
         for xml path('')), 1, 1, '')

set @query 
  = 'select col+'':''+cast(value as varchar(10)) col
     from test
     unpivot
     (
       value
       for col in ('+ @colsunpivot +')
     ) u'

exec(@query)

See SQL Fiddle with Demo

Note: when using UNPIVOT the datatypes of all of the columns that need to be transformed must be the same. So you might have to cast/convert data as needed.

Edit #1, since your datatypes are different on all of your columns and you need to unpivot them, then you can use the following code.

The first piece get the list of columns that you want to unpivot dynamically:

select @colsUnpivot = stuff((select ','+quotename(C.name)
             from sys.columns as C
             where C.object_id = object_id('test')
             for xml path('')), 1, 1, '')

The second piece gets the same list of columns but wraps each column in a cast as a varchar:

select @colsUnpivotCast = stuff((select ', cast('+quotename(C.name)+' as varchar(50)) as '+quotename(C.name)
         from sys.columns as C
         where C.object_id = object_id('test')
         for xml path('')), 1, 1, '')

Then your final query will be:

DECLARE @colsUnpivot AS NVARCHAR(MAX),
    @colsUnpivotCast AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)


select @colsUnpivot = stuff((select ','+quotename(C.name)
         from sys.columns as C
         where C.object_id = object_id('test')
         for xml path('')), 1, 1, '')

select @colsUnpivotCast = stuff((select ', cast('+quotename(C.name)+' as varchar(50)) as '+quotename(C.name)
         from sys.columns as C
         where C.object_id = object_id('test')
         for xml path('')), 1, 1, '')


set @query 
  = 'select col+'':''+value col
     from
    (
      select '+@colsUnpivotCast+'
      from test
    ) src
     unpivot
     (
       value
       for col in ('+ @colsunpivot +')
     ) u'


exec(@query)

See SQL Fiddle with Demo

The UNPIVOT function is performing the same process as a UNION ALL which would look like this:

select col+':'+value as col
from
(
  select A value, 'A' col
  from test
  union all
  select cast(B as varchar(10)) value, 'B' col
  from test
  union all
  select cast(C as varchar(10)) value, 'C' col
  from test
  union all
  select cast(D as varchar(10)) value, 'D' col
  from test
) src

See SQL Fiddle with Demo

The result of all of the queries is the same:

|    COL |
----------
|    A:1 |
| B:2.00 |
|    C:3 |
|    D:4 |

Edit #2: using UNPIVOT strips out any of the null columns which could cause some data to drop. If that is the case, then you will want to wrap the columns with IsNull() to replace the null values:

DECLARE @colsUnpivot AS NVARCHAR(MAX),
    @colsUnpivotCast AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)


select @colsUnpivot = stuff((select ','+quotename(C.name)
         from sys.columns as C
         where C.object_id = object_id('test')
         for xml path('')), 1, 1, '')

select @colsUnpivotCast = stuff((select ', IsNull(cast('+quotename(C.name)+' as varchar(50)), '''') as '+quotename(C.name)
         from sys.columns as C
         where C.object_id = object_id('test')
         for xml path('')), 1, 1, '')


set @query 
  = 'select col+'':''+value col
     from
    (
      select '+@colsUnpivotCast+'
      from test
    ) src
     unpivot
     (
       value
       for col in ('+ @colsunpivot +')
     ) u'


exec(@query)

See SQL Fiddle with Demo

Replacing the null values, will give a result like this:

|    COL |
----------
|    A:1 |
| B:2.00 |
|     C: |
|    D:4 |
like image 126
Taryn Avatar answered Jan 05 '23 00:01

Taryn