Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 General SQL Server Forums
 New to SQL Server Programming
 Dynamic Union All

Author  Topic 

Johnph
Posting Yak Master

103 Posts

Posted - 2014-04-29 : 11:30:42
Hello, I am having a bit of trouble writing a query that dynamically outputs what I need.

I have a table that looks like this:

COL1 AAA BBB CCC
CAT 1 3 3
CAT 1 2 2
CAT 1 4 4
DOG 2 3 3
DOG 5 5 5
MICE 1 1 1

I need it to dynamically output based off COL1, the output should look like this. When there are more rows for CAT, it should output more columns. Kind of like merging the columns

COL1 AAA BBB CCC AAA BBB CCC AAA BBB CCC
CAT 1 3 3 1 2 2 1 4 4
DOG 2 3 3 5 5 5 NULL NULL NULL
MICE 1 1 1 NULL NULL NULL NULL NULL NULL

Lamprey
Master Smack Fu Yak Hacker

4614 Posts

Posted - 2014-04-29 : 11:48:01
What you want is called a pivot, not a union:
http://technet.microsoft.com/en-us/library/ms177410(v=sql.105).aspx

If you need it to truly be dynamic, then you might need to do a dynamic pivot:
http://stackoverflow.com/questions/10404348/sql-server-dynamic-pivot-query
Go to Top of Page

Johnph
Posting Yak Master

103 Posts

Posted - 2014-04-29 : 12:01:58
Is there a link to an example similar to mine with the rows not turning into columns?
Go to Top of Page

MuralikrishnaVeera
Posting Yak Master

129 Posts

Posted - 2014-04-30 : 06:30:43
Hey john,
I done it in 3 ways along with DYNAMIC PIVOT



-------------------------------------------------------------------------------------------------------------------------
--Test Table creation
-------------------------------------------------------------------------------------------------------------------------
CREATE TABLE #TABLE (COL1 VARCHAR(100),AAA INT,BBB INT,CCC INT)
INSERT INTO #TABLE VALUES
('CAT' ,1 ,3 ,3),
('CAT' ,1 ,2 ,2),
('CAT' ,1 ,4 ,4),
('DOG' ,2 ,3 ,3),
('DOG' ,5 ,5 ,5),
('MICE' ,1 ,1 ,1)
-------------------------------------------------------------------------------------------------------------------------
--Retriving Column names dynamically and applying DYNAMIC PIVOT
-------------------------------------------------------------------------------------------------------------------------

DECLARE @Query VARCHAR(MAX)
DECLARE @Col VARCHAR(MAX) = STUFF((SELECT ','+MIN(col) FROM
(select Col1, col+CAST(Rn AS VARCHAR(100)) col,Rn, value
from (SELECT *,ROW_Number ()OVER (PARTITION BY Col1 ORDER BY COl1) AS Rn FROM #Table)a
cross apply
(
select 'AAA', convert(varchar(10), AAA, 120) union all
select 'BBB', convert(varchar(10), BBB, 120) union all
select 'CCC', convert(varchar(10), CCC, 120)
) c (col, value)
)a
GROUP BY col,Rn
ORDER BY Rn
FOR XML PATH('')),1,1,'')

SET @Query =N'
SELECT Col1,'+@Col+' FROM
(
select Col1, col+CAST(Rn AS VARCHAR(100)) col, value
from (SELECT *,ROW_Number ()OVER (PARTITION BY Col1 ORDER BY COl1) AS Rn FROM #Table)a
cross apply
(
select ''AAA'', convert(varchar(10), AAA, 120) union all
select ''BBB'', convert(varchar(10), BBB, 120) union all
select ''CCC'', convert(varchar(10), CCC, 120)
) c (col, value)
)a
PIVOT (MAX(value) FOR Col in('+@Col+')) AS PVT'
EXECUTE (@Query)


-------------------------------------------------------------------------------------------------------------------------
--MeanWhile there are two Static approches to achieve this
--1.Using Case Statements
--2.CTE Concept
-------------------------------------------------------------------------------------------------------------------------
SELECT Col1
,MAX(CASE WHEN Rn =1 THEN AAA END) AS AAA
,MAX(CASE WHEN Rn =1 THEN BBB END) AS BBB
,MAX(CASE WHEN Rn =1 THEN CCC END) AS CCC
,MAX(CASE WHEN Rn =2 THEN AAA END) AS AAA
,MAX(CASE WHEN Rn =2 THEN BBB END) AS BBB
,MAX(CASE WHEN Rn =2 THEN CCC END) AS CCC
,MAX(CASE WHEN Rn =3 THEN AAA END) AS AAA
,MAX(CASE WHEN Rn =3 THEN BBB END) AS BBB
,MAX(CASE WHEN Rn =3 THEN CCC END) AS CCC
FROM (SELECT *,ROW_Number ()OVER (PARTITION BY Col1 ORDER BY COl1) AS Rn FROM #Table)a
GROUP BY Col1
-------------------------------------------------------------------------------------------------------------------------

;WITH cte1
AS(
SELECT *,ROW_Number ()OVER (PARTITION BY Col1 ORDER BY COl1) AS Rn FROM #Table
)
,cte2
AS
(
SELECT * FROM cte1 WHERE Rn=1
)
,cte3
AS(
SELECT * FROM cte1 WHERE Rn =2
)
,cte4
AS
(
SELECT * FROM cte1 WHERE Rn =3
)
SELECT t2.COl1,t2.AAA,t2.BBB,t2.CCC,t3.AAA,t3.BBB,t3.CCC,t4.AAA,t4.BBB,t4.CCC FROM
cte2 As t2 LEFT JOIN cte3 As t3 ON t2.COl1= t3.COl1
LEFT JOIN cte4 t4 on t4.COl1 = t2.COl1


-------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------
--DROP TABLE
DROP TABLE #TABLE
-------------------------------------------------------------------------------------------------------------------------





---------------
Murali Krishna

You live only once ..If you do it right once is enough.......
Go to Top of Page
   

- Advertisement -