-3

I work on SQL Server 2012 and I have an issue: I can't represent rows as columns.

I need to represent code type from details table to display as column with values of count parts from details table, join between master and details by plid. Every plid have a group of code type so instead of represent code type as rows, I will represent it as columns. Columns will have header as code type and content column will be count parts.

How to do that?

create table #master
 (
 zplid int,
 zplidname  nvarchar(50)
 )
 insert into #master(zplid,zplidname) 
 values
 (4124,'tetanium'),
 (4125,'FilmCapacitor'),
 (4145,'CeramicCapacitor'),
 (4170,'Holetransistor'),
 (4190,'resistor')

 create table #details
 (
 zplid int,
 CodeType  int,
 CountParts int
 )
 insert into #details(zplid,CodeType,CountParts) 
 values
 (4124,9089,9011),
 (4124,7498,7000),
 (4125,9089,2000),
 (4125,7498,1000),
 (4145,9089,3000),
 (4145,7498,8500),
 (4170,9089,7600),
 (4170,7498,6600),
 (4190,9089,9001),
 (4190,7498,9003)

Result:

join between master and details

0

1 Answer 1

1

You'll want to use the PIVOT operator in SQL Server. (Note UNPIVOT is really useful to know as well).

This StackOverflow Answer gives a really good walkthrough on how to utilize PIVOT.

You basically want a query like this:

WITH CTE_MasterDetails AS -- Join your Master and Details together first in a CTE
(
    SELECT M.zplid, M.zplidname, D.CodeType, D.CountParts
    FROM #master AS M
    LEFT JOIN #details AS D -- Left joining just in case not all Master records have a corresponding Details record
        ON M.zplid = D.zplid
)

-- Final select from the CTE above, using a PIVOT to transpose the rows as columns
SELECT *
FROM 
(
    SELECT zplid, zplidname, CountParts, CodeType
    FROM CTE_MasterDetails
) SRC -- This is the source of the following Pivot operation
PIVOT
(
    MAX(CountParts) -- Value field
    FOR CodeType IN ([9089], [7498]) -- Pivoted Column Headers (on CodeType column's values)
) PIV
ORDER BY zplid;

The above example outputs the following results (using your sample scripts to build the #Master and #Details tables):

Results


Here's an example query with the same output as above but using dynamic SQL to dynamically generate the columns on CodeType:

DECLARE @Cols AS NVARCHAR(MAX), -- To hold the dynamically generated column list string
        @Query AS NVARCHAR(MAX) -- To hold the dynamic SQL of the Pivot query

-- Dynamically generate the column list string
SELECT @Cols = 
    STUFF
    (
        (
            SELECT ',[' + CAST(CodeType AS NVARCHAR(MAX)) + ']'
            FROM #Details
            GROUP BY CodeType
            ORDER BY CodeType DESC
            FOR XML PATH('')
        ),
        1,
        1,
        ''
    )

-- Dynamic SQL of the Pivot query
SET @Query =
'
WITH CTE_MasterDetails AS
(
    SELECT M.zplid, M.zplidname, D.CodeType, D.CountParts
    FROM #master AS M
    LEFT JOIN #details AS D
        ON M.zplid = D.zplid
)

SELECT *
FROM 
(
  SELECT zplid, zplidname, CountParts, CodeType
  FROM CTE_MasterDetails
) SRC
PIVOT
(
  MAX(CountParts)
  FOR CodeType IN (' + @Cols + ')
) PIV
ORDER BY zplid;
'

-- Executing the dynamic SQL generated above
EXEC sp_ExecuteSQL @Query
0

Not the answer you're looking for? Browse other questions tagged or ask your own question.