Hi I have two tables Attribute, Instance
Attribute Table
id | key_info | value_info
2 | amount | 1009
2 | currency | USD
2 | Level | Level 5
3 | amount | 2017
3 | currency | CAD
Instance Table
id | status
2 | Pending
3 | Approved
I want to join two tables like this-
New table
id | amount | currrency | level | status
2 | 1001 | USD | Level 5 | Pending
3 | 2017 | CAD | | Approved
All the fields in the Attribute and Instance are optional except id.
Here's how you can transpose cell content: Copy the cell range. Select the empty cells where you want to paste the transposed data. On the Home tab, click the Paste icon, and select Paste Transpose.
A conditional column join is a fancy way to let us join to a single column and to two (or more) columns in a single query. We can accomplish this by using a case statement in the on clause of our join. A case statement allows us to test multiple conditions (like an if/else if/else) to produce a single value.
select
a.id,
max(case when a.key_info = 'amount' then a.value_info end) as amount,
max(case when a.key_info = 'currency' then a.value_info end) as currency,
max(case when a.key_info = 'level' then a.value_info end) as level,
i.status
from
attribute a
join instance i on a.id = i.id
group by
a.id,
i.status
Starting in SQL Server 2005, the PIVOT
function can perform this conversion from rows to columns:
select id,
amount,
currency,
level,
status
from
(
select i.id, i.status,
a.key_info,
a.value_info
from instance i
inner join attribute a
on i.id = a.id
) src
pivot
(
max(value_info)
for key_info in (amount, currency, level)
) piv
See SQL Fiddle with Demo.
If you have an unknown number of key_values
then you can use dynamic SQL:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT distinct ',' + QUOTENAME(key_info)
from Attribute
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT id, ' + @cols + ', status from
(
select i.id, i.status,
a.key_info,
a.value_info
from instance i
inner join attribute a
on i.id = a.id
) x
pivot
(
max(value_info)
for key_info in (' + @cols + ')
) p '
execute(@query)
See SQL Fiddle with Demo. Both give the result:
| ID | AMOUNT | CURRENCY | LEVEL | STATUS |
-----------------------------------------------
| 2 | 1009 | USD | Level 5 | Pending |
| 3 | 2017 | CAD | (null) | Approved |
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With