How to pivot based on two column - sql

i have a table as follows
and my expected output is as follows.
SQL Fiddle for this problem
In expected output ,it need to be pivoted by combination of id & date .
How can i solve this problem ?

There is not any PIVOT function in sql lite. Which the link that you have supplied leads to. But you could do this:
SELECT
yourtable.Id,
yourtable.Date,
MAX(CASE WHEN [Type]=1 THEN [Value] ELSE NULL END) AS [1],
MAX(CASE WHEN [Type]=2 THEN [Value] ELSE NULL END) AS [2],
MAX(CASE WHEN [Type]=3 THEN [Value] ELSE NULL END) AS [3]
FROM
yourtable
GROUP BY
yourtable.Id,
yourtable.Date
If you want to do it with an pivot and are using MSSQL 2012. Then you can do this:
SELECT
*
FROM
(
SELECT
yourtable.Id,
yourtable.Date,
yourtable.Type,
yourtable.Value
FROM
yourtable
) AS sourceTable
PIVOT
(
MAX(Value)
FOR Type IN([1],[2],[3],[4])
) AS pvt
This will result in this:
1 2014-04-01 00:00:00.000 23 NULL NULL NULL
2 2014-04-01 00:00:00.000 56 NULL NULL NULL
3 2014-04-01 00:00:00.000 12 78 NULL NULL
2 2014-07-01 00:00:00.000 56 NULL NULL NULL
3 2014-07-01 00:00:00.000 12 78 33 NULL

Related

Convert Rows to columns with variable number [duplicate]

This question already has answers here:
Group by column and multiple Rows into One Row multiple columns
(2 answers)
Closed 6 months ago.
I have read stuff on pivot tables and I am still having problems getting this correct.
I have a table where column 1 is a Productnr, and column 2 is LHS, column 3 is another Productnr and lastly column 4 is RHS. Also the number of entries of Productnr2 (belonging to Productnr) is variable between 1 and 5. For example, if there are only 3 associated Productnr2 (see article no = 060013 in Productnr) then the last two columns should remain empty.
Productnr LHS Productnr2 RHS
060009 411 099088 5
060013 228 194139 25
060013 228 194141 17
060013 228 175823 75
060022 951 147071 90
060034 424 099088 14
060034 424 102704 88
060034 424 080034 82
060034 424 108436 87
060034 424 108437 58
I would like it to come out as a pivot table, like this:
Productnr | LHS | 1 | RHS | 2 | RHS | 3 | RHS | 4 | RHS | 5 | RHS |
-----
060009 411 099088 5
060013 228 194139 25 194141 17 175823 75
060022 951 147071 90
060034 424 099088 14 102704 88 080034 82 108436 87 108437 58
This can achieve by the following query. But this will work only for five different columns only, if more columns needed then need to increase the case count, but this is not recommended. Better try some dynamic queries for more columns.
CREATE TABLE #temp(Productnr INT, LHS INT, Productnr2 INT, RHS INT)
INSERT INTO #temp VALUES (060009,411,099088,5 )
INSERT INTO #temp VALUES (060013,228,194139,25)
INSERT INTO #temp VALUES (060013,228,194141,17)
INSERT INTO #temp VALUES (060013,228,175823,75)
INSERT INTO #temp VALUES (060022,951,147071,90)
INSERT INTO #temp VALUES (060034,424,099088,14)
INSERT INTO #temp VALUES (060034,424,102704,88)
INSERT INTO #temp VALUES (060034,424,080034,82)
INSERT INTO #temp VALUES (060034,424,108436,87)
INSERT INTO #temp VALUES (060034,424,108437,58)
;WITH CTE AS(
SELECT *
,ROW_NUMBER() OVER(PARTITION BY Productnr ORDER BY Productnr)RN
FROM #temp
)
SELECT Productnr,LHS
,MAX(CASE WHEN RN=1 THEN Productnr2 END) [1]
,MAX(CASE WHEN RN=1 THEN RHS END) [RHS]
,MAX(CASE WHEN RN=2 THEN Productnr2 END) [2]
,MAX(CASE WHEN RN=2 THEN RHS END) [RHS]
,MAX(CASE WHEN RN=3 THEN Productnr2 END) [3]
,MAX(CASE WHEN RN=3 THEN RHS END) [RHS]
,MAX(CASE WHEN RN=4 THEN Productnr2 END) [4]
,MAX(CASE WHEN RN=4 THEN RHS END) [RHS]
,MAX(CASE WHEN RN=5 THEN Productnr2 END) [5]
,MAX(CASE WHEN RN=5 THEN RHS END) [RHS]
FROM CTE
GROUP BY Productnr,LHS
DROP TABLE #temp
Output:
Productnr LHS 1 RHS 2 RHS 3 RHS 4 RHS 5 RHS
----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- -----------
60009 411 99088 5 NULL NULL NULL NULL NULL NULL NULL NULL
60013 228 194139 25 194141 17 175823 75 NULL NULL NULL NULL
60022 951 147071 90 NULL NULL NULL NULL NULL NULL NULL NULL
60034 424 99088 14 102704 88 80034 82 108436 87 108437 58

SQL Server - Transpose Date from One Table To Another

Can't figure out how to transpose data from one table to another. Do I use a cursor?
Sample Data:
Build Part SN DateShipped
A 1 123 2017-01-01
A 2 234 2017-02-02
A 3 345 2017-03-03
B 1 987 2017-01-01
B 2 876 2017-02-02
B 3 765 2017-03-03
Desired Result:
Build Part1SN Part1Ship Part2SN Part2Ship Part3SN Part3Ship
A 123 2017-01-01 234 2017-02-02 345 2017-03-03
B 987 2017-01-01 876 2017-02-02 765 2017-03-03
Since you are mixing data types (date & int) in the Pivot, I'll give a working example of a dynamic Pivot. Date note of what we are doing within the Cross Apply.
I'm also assuming Part is sequential within build, otherwise we would need to apply/nest a Row_Number()
Example
Declare #SQL varchar(max) = '
Select *
From (
Select A.Build
,B.*
From YourTable A
Cross Apply ( values (concat(''Part'',A.Part,''SN''), concat('''',A.SN))
,(concat(''Ship'',A.Part,''Ship''),concat('''',A.DateShipped))
) B (Item,Value)
) A
Pivot (max([Value]) For [Item] in (' + Stuff((Select ','+QuoteName(concat('Part',Part,'SN'))
+','+QuoteName(concat('Ship',Part,'Ship'))
From (Select Distinct Part From YourTable ) A
Order By 1
For XML Path('')),1,1,'') + ') ) p'
Exec(#SQL)
--Print #SQL
Returns
The Generated SQL Looks Like This
Select *
From (
Select A.Build
,B.*
From YourTable A
Cross Apply ( values (concat('Part',A.Part,'SN'), concat('',A.SN))
,(concat('Ship',A.Part,'Ship'),concat('',A.DateShipped))
) B (Item,Value)
) A
Pivot (max([Value]) For [Item] in ([Part1SN],[Ship1Ship],[Part2SN],[Ship2Ship],[Part3SN],[Ship3Ship]) ) p
select Build,
max(case Part when 1 then SN end) 'Part1SN', max(case Part when 1 then DateShipped end) 'Part1Ship',
max(case Part when 2 then SN end) 'Part2SN', max(case Part when 2 then DateShipped end) 'Part2Ship',
max(case Part when 3 then SN end) 'Part3SN', max(case Part when 3 then DateShipped end) 'Part3Ship'
from TempTable
group by Build
You should try using pivot Table.
For reference follow the below link
https://www.sqlshack.com/multiple-options-to-transposing-rows-into-columns/

query table to reorganise data

I have the following table, tblCPDates
cDate date
cp nvarchar(10)
Example of the data
cDate cp
2016-01-01 AB
2016-01-01 MN
2016-02-01 EF
2016-03-01 AB
2016-04-01 MN
What I would like
cDate AB MN EF
2016-01-01 1 1 0
2016-02-01 0 0 1
2016-03-01 1 0 0
2016-04-01 0 1 0
Is this possible?
I tried the following but obviously only return the last date
select * from
(
select distinct cDate, cp from tblCPDDates
)source pivot(max(cDate) for cp in ([AB], [MN], [EF])) as pvt
You could do this with an aggregated CASE;
Sample Data
CREATE TABLE #tblCPDates (cDate date, cp nvarchar(10))
INSERT INTO #tblCPDates (cDate, cp)
VALUES
('2016-01-01','AB')
,('2016-01-01','MN')
,('2016-02-01','EF')
,('2016-03-01','AB')
,('2016-04-01','MN')
Query
SELECT
cDate
,SUM(CASE WHEN cp = 'AB' THEN 1 ELSE 0 END) AB
,SUM(CASE WHEN cp = 'MN' THEN 1 ELSE 0 END) MN
,SUM(CASE WHEN cp = 'EF' THEN 1 ELSE 0 END) EF
FROM #tblCPDates
GROUP BY cDate
Output
cDate AB MN EF
2016-01-01 1 1 0
2016-02-01 0 0 1
2016-03-01 1 0 0
2016-04-01 0 1 0
try this out : by using pivot it is more easier :
CREATE TABLE #tblCPDates (cDate date, cp nvarchar(10))
INSERT INTO #tblCPDates (cDate, cp)
VALUES
('2016-01-01','AB')
,('2016-01-01','MN')
,('2016-02-01','EF')
,('2016-03-01','AB')
,('2016-04-01','MN')
select *
from
(
select cDate, cp
from #tblCPDates
) src
pivot
(
Count(cp)
for cp in ([AB], [MN],[EF])
) piv;
TryThis.
select
cDate ,
case when ab='AB' then 1 else 0 end as AB,
case when MN='MN' then 1 else 0 end as MN,
case when EF='EF' then 1 else 0 end as EF
from
(
select distinct cDate, cp from tblCPDates
)source pivot(max(cp) for cp in ([AB], [MN], [EF])) as pvt
Using pivot for get result :
`CREATE TABLE #table(Id INT,cDate DATE,cp VARCHAR(10))
INSERT INTO #table(Id,cDate ,cp )
SELECT 1,'2016-01-01','AB' UNION ALL
SELECT 1,'2016-01-01','MN' UNION ALL
SELECT 1,'2016-02-01','EF' UNION ALL
SELECT 1,'2016-03-01','AB' UNION ALL
SELECT 1,'2016-04-01','MN'
SELECT cDate,ISNULL([AB],0) [AB],ISNULL([MN],0) [MN],ISNULL([EF],0) [EF]
FROM
( SELECT Id,cDate ,cp FROM #table ) A PIVOT (MAX(Id) FOR cp IN ([AB],[MN],[EF])) pvt`

sql pivot on multiple values

Given the following data table
Id Code Date PIVOT VALUE1 VALUE2
1 WMAZ 2014-01-31 12:23:06.000 1 103 1
2 EEEE 2014-01-31 11:59:15.000 2 74 2
3 WMAZ 2014-01-31 11:59:10.000 1 3 3
4 WMAZ 2014-01-31 11:56:55.000 2 10 4
5 WMAZ 2014-01-31 11:56:14.000 2 96 5
6 EEEE 2014-01-31 11:55:26.000 2 159 6
I need to pivot the data to get this:
Code Date SUMVALUE1FORPIVOT1 SUMVALUE1FORPIVOT2 SUMVALUE2FORPIVOT1 SUMVALUE2PIVOT2
WMAZ 2014-01-31 (103+3) (10+96) (1+3) (4+5)
EEEE 2014-01-31 NULL (74+159) NULL (6+2)
How do I get a sum for value1 and value2 for each pivot grouped by Code and Date without writing a sub-query for each field?
You could do something like this:
Test data
DECLARE #tbl TABLE(Id INT,Code VARCHAR(100),
Date DATETIME,
[PIVOT] INT,
VALUE1 INT,
VALUE2 INT)
INSERT INTO #tbl
VALUES
(1,'WMAZ','2014-01-31 12:23:06.000',1,103,1),
(2,'EEEE','2014-01-31 11:59:15.000',2,74,2),
(3,'WMAZ','2014-01-31 11:59:10.000',1,3,3),
(4,'WMAZ','2014-01-31 11:56:55.000',2,10,4),
(5,'WMAZ','2014-01-31 11:56:14.000',2,96,5),
(6,'EEEE','2014-01-31 11:55:26.000',2,159,6)
Query
SELECT
tbl.Code,
CAST(tbl.Date AS DATE) AS Date,
SUM(CASE WHEN [PIVOT]=1 THEN VALUE1 ELSE NULL END) AS SUMVALUE1FORPIVOT1,
SUM(CASE WHEN [PIVOT]=2 THEN VALUE1 ELSE NULL END) AS SUMVALUE1FORPIVOT2,
SUM(CASE WHEN [PIVOT]=1 THEN VALUE2 ELSE NULL END) AS SUMVALUE2FORPIVOT1,
SUM(CASE WHEN [PIVOT]=2 THEN VALUE2 ELSE NULL END) AS SUMVALUE2FORPIVOT2
FROM
#tbl AS tbl
GROUP BY
tbl.Code,
CAST(tbl.Date AS DATE)
ORDER BY
tbl.Code DESC
Result:
Code Date SUMVALUE1FORPIVOT1 SUMVALUE1FORPIVOT2 SUMVALUE2FORPIVOT1 SUMVALUE2PIVOT2
---------------------------------------------------------------------------------------------------
WMAZ 2014-01-31 106 106 4 9
EEEE 2014-01-31 NULL 233 NULL 8

PIVOT values from two columns to multiple columns

Table: Sample
ID Day Status MS
----------------------------
1 1 0 10
1 2 0 20
1 3 1 15
2 3 1 3
2 30 0 5
2 31 0 6
Expected Result:
ID Day1 Day2 Day3....Day30 Day31 Status1 Status2 Status3...Status30 Status31
---------------------------------------------------------------------------------------
1 10 20 15 NULL NULL 0 0 1 NULL NULL
2 NULL NULL 3 5 6 NULL NULL 1 0 0
I want to get the MS and Status value for each day from 1 to 31 for each ID.
I have used PIVOT to get the below result.
Result:
ID Day1 Day2 Day3....Day30 Day31
-------------------------------------
1 10 20 15 NULL NULL
2 NULL NULL 3 5 6
Query:
SELECT
ID
,[1] AS Day1
,[2] AS Day2
,[3] AS Day3
.
.
.
,[30] AS Day30
,[31] AS Day31
FROM
(
SELECT
ID
,[Day]
,MS
FROM
Sample
) AS A
PIVOT
(
MIN(MS)
FOR [Day] IN([1],[2],[3],...[30],[31])
) AS pvtTable
How can I merge the Status column with the result?.
Try this. Use Another Pivot to transpose Status column. Then use aggregate (Max or Min) in select column list with group by Id to get the Result.
CREATE TABLE #est
(ID INT,[Day] INT,[Status] INT,MS INT)
INSERT #est
VALUES (1,1,0,10),(1,2,0,20),(1,3,1,15 ),
(2,3,1,3),(2,30,0,5),(2,31,0,6)
SELECT ID,
Max([Day1]) [Day1],
Max([Day2]) [Day2],
Max([Day3]) [Day3],
Max([Day30]) [Day30],
Max([Day31]) [Day31],
Max([status1]) [status1],
Max([status2]) [status2],
Max([status3]) [status3],
Max([status30])[status30],
Max([status31])[status31]
FROM (SELECT Id,
'status' + CONVERT(VARCHAR(30), Day) col_stat,
'Day' + CONVERT(VARCHAR(30), Day) Col_Day,
[status],
ms
FROM #est) a
PIVOT (Min([ms])
FOR Col_Day IN([Day1],[Day2],[Day3],[Day30],[Day31])) piv
PIVOT (Min([status]) FOR col_stat IN ([status1],[status2],[status3],[status30],[status31])) piv1
GROUP BY id