I am using Sql Server 2012 for my DBMS.
In my database I have a Product table that is related to a series of catalog tables. These catalog tables represent the various Product Categories. The idea being that while all products have certain attributes in common (our internal identifier for it, a supplier, a cost, etc) the specifics of the products will vary (furniture is not described the same way as a digital product would be described).
Additionally, each product has a parent entity. A parent may have multiple children (or products in this case).
My task is to select the products and related information for a given list of parent Id's and populate that information into an XML document.
The tables I'm currently working with are:
- PRODUCT
- PRODUCT_DIGITAL
- PRODUCT_FURNITURE
Product has a PK/FK relationship with PRODUCT_DIGITAL on Product_Id. Same type of relationship exist for PRODUCT to PRODUCT_FURNITURE.
If product looks like this:
PRODUCT_ID -- PRODUCT_CATEGORY -- PARENT_ID -- PARENT_TYPE -- DELIVERY_IN_DAYS
100 DIG 1 1 7
101 DIG 1 1 8
102 DIG 1 1 1
103 DIG 2 1 2
104 DIG 2 1 1
And PRODUCT_DIGITAL looks like this:
PRODUCT_ID -- PRODUCT_TYPE -- PRODUCT_NAME -- PRODUCT_MNEMONIC
100 A IMG1 IMAWTRFL
101 B SND1 SNDENGRV
102 B SND2 SNDHRSLF
103 A IMG2 IMGNBRTO
104 B SND3 SNDGTWNE
In the end I want result set that looks like this:
PRODUCT_CATEGORY -- PRODUCT_ID -- PRODUCT_TYPE -- PARENT_ID -- DELIVERY_IN_DAYS -- PROD_EXTENSION_NAME -- PROD_EXTENSION_TYPE -- PROD_EXTENSION_VALUE
DIG 100 A 1 7 PRODUCT_NAME STRING IMG1
DIG 100 A 1 7 PRODUCT_MNEMONIC STRING IMAWTRFL
DIG 101 B 1 8 PRODUCT_NAME STRING SND1
DIG 101 B 1 8 PRODUCT_MNEMONIC STRING SNDENGRV
DIG 102 B 1 1 PRODUCT_NAME STRING SND2
DIG 102 B 1 1 PRODUCT_MNEMONIC STRING SNDHRSLF
DIG 103 A 2 2 PRODUCT_NAME STRING IMG2
DIG 103 A 2 2 PRODUCT_MNEMONIC STRING IMGNBRTO
DIG 104 B 2 1 PRODUCT_NAME STRING SND3
DIG 104 B 2 1 PRODUCT_MNEMONIC STRING SNDGTWNE
My original searching brought me to UNPIVOT - but so far I have not been able to get my head around it. What I ended up doing was creating a temp table and updating it in passes, then joining back to the products table for the final select:
create table #tbl(product_id int, prod_extension_name varchar(100), prod_extension_type varchar(100), prod_extension_value varchar(1000))
insert into #tbl
select p.product_id, c.column_name,
case c.data_type
when 'varchar' then 'string'
else data_type end as data_type
, null
from dbo.product p, information_schema.columns c
where c.table_name = 'PRODUCT_DIGITAL'
and c.column_name in ('PRODUCT_NAME','PRODUCT_MNEMONIC')
update #tbl
set prod_extension_value = p.product_name
from dbo.product p
where #tbl.product_id = p.product_id
and #tbl.colname = 'PRODUCT_NAME'
update #tbl
set prod_extension_value = p.product_mnemonic
from dbo.product p
where #tbl.product_id = p.product_id
and #tbl.colname = 'PRODUCT_MNEMONIC'
select p.product_category, p.product_id, pd.product_category, #tbl.prod_extension_name, #tbl.prod_extension_type, #tbl.prod_extension_value
from dbo.product p inner join dbo.product_digital pd on p.product_id = pd.product_id
inner join #tbl on p.product_id = #tbl.product_id
order by product_id
Can someone point me to a better way to do this? It seems like I should be able to do this faster, without having to make multiple updates, etc.