Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I combine two columns into single column in dynamic pivot

I have a schema like this

demo(id, val, month, year, decide)

Demo data and schema is given in this fiddle http://sqlfiddle.com/#!3/dd89d5/1

In output i want to transform the rows to columns. In the output i want,

ID    (11 14)  (12 14) (2 15) ...     decider
101    0.45     0.5      0.3          411
102    0.4      0.2      0.1          411

I want the month, year to be sorted

I went through lot of threads and found a fiddle. And tried to customize to suit my need

Here is what i tried http://sqlfiddle.com/#!3/dd89d5/1

But could not get the solution. Please help me

like image 612
sanjay Kumar Avatar asked Dec 01 '25 14:12

sanjay Kumar


1 Answers

Here is your table

create table demo(
    id varchar(max),    val decimal(4,2),    month int,    year int, decider int
  )

INSERT INTO demo
    ([id], [val], [month], [year], [decider])
VALUES

(101, 0.25, 11, 14, 411),
(101, 1, 12, 14, 411),
(101, 0.5, 1, 15, 411),
(101, 0.75, 2, 15, 411),
(102, 0.25, 11, 14, 411),
(102, 0.5, 12, 14, 411),
(102, 0.25, 1, 15, 411),
(101, 0.75, 11, 14, 412),
(101, 0.5, 1, 15, 412),
(101, 0.25, 2, 15, 412),
(102, 0.5, 11, 14, 412),
(102, 0.5, 12, 14, 412),
(103, 0.25, 1, 15, 412),
(103, 0.5, 11, 14, 411)
;

Use Dense_Rank to order the column for pivot

SELECT DENSE_RANK() OVER(ORDER BY [YEAR] ,[MONTH]) RNO,*,CAST([MONTH] AS VARCHAR) + ' ' +  CAST([YEAR] AS VARCHAR) DT
INTO #TEMP
FROM
(
    SELECT ID,SUM(VAL)VAL,[MONTH],[YEAR],DECIDER
    FROM DEMO 
    GROUP BY ID,[MONTH],[YEAR],DECIDER
)TAB

Select the columns for pivot and declare a variable to replace NULL with zero

DECLARE @cols NVARCHAR (MAX)
DECLARE @NullToZeroCols NVARCHAR (MAX)

SELECT @cols = COALESCE (@cols + ',[' + DT + ']', 
              '[' + DT + ']')
               FROM    (SELECT DISTINCT RNO,DT FROM #TEMP) PV  
               ORDER BY RNO

SET @NullToZeroCols = SUBSTRING((SELECT ',ISNULL(['+DT+'],0) AS ['+DT+']' 
FROM(SELECT DISTINCT DT,RNO FROM #TEMP GROUP BY DT,RNO)TAB  
ORDER BY RNO  FOR XML PATH('')),2,8000)

Now pivot it

DECLARE @query NVARCHAR(MAX)
SET @query = 'SELECT P.ID,' + @NullToZeroCols + ',DECIDER FROM 
             (
                 SELECT ID, DT, val,DECIDER FROM #TEMP
             ) x
             PIVOT 
             (
                 SUM(val)
                 FOR DT IN (' + @cols + ')
            ) p
            ORDER BY ID;' 

EXEC SP_EXECUTESQL @query

Result

enter image description here

Here is the Fiddle http://sqlfiddle.com/#!3/95111/1 (If any error occur on load press RUNSQL)

like image 137
Sarath KS Avatar answered Dec 04 '25 06:12

Sarath KS



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!