Question

I am stuck on finding a solution to transpose source data from a system via a metadata look-up table into a destination table. I need a method of transpose/pivot the source data into columns (which are by the various data-types). The datatypes for each column are listed in a metadata table.

Table Name: SRC

SrcID    AGE    City      Date
------------------------------------
01       32     London    01-01-2013
02       35     Lagos     02-01-2013
03       36     NY        03-01-2013

Table Name: Metadata

MetaID        Column_Name           Column_type
-------------------------------------------------
11            AGE                   col_integer
22            City                  col_character
33            Date                  col_date

Destination table:

The source data to be loaded into the destination table(as shown below):

Destination table:

SrcID     MetaID     col_int     col_char     col_date
---------------------------------------------------------
01        11         32             -            -    
01        22            -        London          -    
01        33            -           -          01-01-2013
02        11         35             -               - 
02        22             -       Lagos              -
02        33             -          -          02-01-2013
03        11         36             -               - 
03        22             -         NY               -
03        33             -          -          03-01-2013

Any help would would be much appreciated.

Thank you,

Was it helpful?

Solution

Sample queries and STEPs given below.

select srcid, metaid, col_integer, col_character,col_date
from
(
select SrcId, 
CAST(AGE AS NVARCHAR(MAX)) AS AGE, 
CAST(City AS NVARCHAR(MAX)) AS City, 
CAST([Date] AS NVARCHAR(MAX)) AS [Date]
from src
) as dat
unpivot
(
ColVal for Columz IN (AGE, City, [Date])
) as upiv
left join metadata as m
on upiv.Columz = m.Column_name
pivot(
max(ColVal)
for Column_type in ([col_integer], [col_character], [col_date])
) as piv1

Sample SQL fiddle to test these queries (It work on SQLs 2008 or greater) - http://sqlfiddle.com/#!3/e5e38b/1


Steps given below in case you want to learn -

Step 1 -

Wish that we can join age column of SRC to age row of meta. So, we converts the SRC columns to rows using unpivot.

select * 
from
(
-- Unpivot query. You need to cast it, 
-- otherwise you get an error
select SrcId, 
CAST(AGE AS NVARCHAR(MAX)) AS AGE, 
CAST(City AS NVARCHAR(MAX)) AS City, 
CAST([Date] AS NVARCHAR(MAX)) AS [Date]
from src
) as dat
unpivot
(
ColVal for Columz IN (AGE, City, [Date])
) as upiv

Note - Why are we casting ? Refer this - UNPIVOT on Table in a Different Server/Database Fails with 'conflicts with the type of other columns' error

Output -

SrcId, ColVal, Columz
1,32,AGE
1,London,City
1,2013-01-01,Date
2,35,AGE
2,Lagos,City
2,2013-02-01,Date
3,36,AGE
3,NY,City
3,2013-03-01,Date

STEP 2 -

Now we are a ready to join the metadata table. We simply add the following join to above code -

left join metadata as m
on upiv.Columz = m.Column_name

Output -

SrcId,ColVal,Columz,MetaId,Column_Name,Column_Type
1,32,AGE,11,AGE,col_integer
1,London,City,22,City,col_character
1,2013-01-01,Date,33,Date,col_date
2,35,AGE,11,AGE,col_integer
2,Lagos,City,22,City,col_character
2,2013-02-01,Date,33,Date,col_date
3,36,AGE,11,AGE,col_integer
3,NY,City,22,City,col_character
3,2013-03-01,Date,33,Date,col_date

STEP 3 -

We now see that we want to convert those rows in the Column_Type column to columns as per your need. So we uses a PIVOT. We add the following code to above code

pivot(
max(ColVal)
for Column_type in ([col_integer], [col_character], [col_date])
) as piv1

Output -

SrcId,Columz,MetaId,Column_Name,col_integer,col_character,col_date
1,AGE,11,AGE,32,NULL,NULL
1,City,22,City,NULL,London,NULL
1,Date,33,Date,NULL,NULL,2013-01-01
2,AGE,11,AGE,35,NULL,NULL
2,City,22,City,NULL,Lagos,NULL
2,Date,33,Date,NULL,NULL,2013-02-01
3,AGE,11,AGE,36,NULL,NULL
3,City,22,City,NULL,NY,NULL
3,Date,33,Date,NULL,NULL,2013-03-01

STEP 4 -

This result has some extra columns. To remove the extra columns change first line in STEP 1, i.e select * to select srcid, metaid, col_integer, col_character,col_date

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top