How to Un Pivot the Table With Date Headers in Sql - sql

I have the following Temp table with Date Header How to UnPivot this Table
I need Like This type result

Here is the solution to your Problem:
DECLARE #colsUnpivot AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #colsUnpivot
= stuff((select ','+quotename(C.name)
FROM sys.columns c
WHERE c.object_id = OBJECT_ID('table')
for xml path('')), 1, 1, '')
set #query
= 'select sno,EmpId, Name, Date, Value
from table
unpivot
(
Date
FOR EmpId IN ('+ #colsunpivot +')
) u'
exec sp_executesql #query;
I used dynamic query since if you don't know how much columns are there in your table.
You can also use below static query :
SELECT sno, EmpId, Name, Date, Value
FROM
(SELECT *
FROM table) p
UNPIVOT
(Date FOR EmpId IN
(01-Mar-18,02-Mar-18,03-Mar-18,04-Mar-18,05-Mar-18)
)AS unpvt;

try the following script:
SELECT [s#no], [Emp#ID], [Name], [Date], [Shiftid]
FROM
(SELECT * FROM table_name) SRC
UNPIVOT
([Date] FOR [Emp#ID]
IN ([01-Mar-18], [02-Mar-18], [03-Mar-18], [04-Mar-18], [05-Mar-18])
) UNPVT;

Related

SQL Server Convert Rows Into Columns

I have a table like this with 145.695 rows.
SERVER
TAPE
ACS08
M00030L3
ACS08
M00253L3
ACS09
M00580L3
ACS09
M00602L3
ACS10
M00580L4
ACS10
M00602L5
ACS10
M00602L7
Now I want to reach a target table structure like this:
ACS08
ACS09
ACS10
M00030L3
M00580L3
M00580L4
M00253L3
M00602L3
M00602L5
M00602L7
I need help because I dont know how can I do.
You can use dynamic pivot to get the desired results.
First we need to generate the dynamic columns based on the [SERVER] column values and then pivot the values as per the requirement:
DECLARE #cols NVARCHAR(MAX), #query NVARCHAR(MAX);
SET #cols = STUFF((SELECT DISTINCT ','+ QUOTENAME([SERVER])
FROM T FOR XML PATH(''), TYPE
).value('.', 'nvarchar(max)'), 1, 1, ''); --XML way of getting the column values
SET #query = 'SELECT '+#cols+' from
(
SELECT [SERVER], [TAPE], ROW_NUMBER() OVER (PARTITION BY [SERVER] ORDER BY (SELECT NULL)) as RN --We need to add a unique number to select all rows while doing aggregation for the PIVOT
FROM T
)x
PIVOT (max([TAPE]) for [SERVER] in ('+#cols+')
) PVT';
EXECUTE (#query);
Please find the db<>fiddle here.
Try this:
DECLARE #Columns nvarchar(max), #Sql nvarchar(max);
SELECT
#Columns =
STRING_AGG(
'MAX(CASE [Server] WHEN ' + QUOTENAME([Server], '''') + ' THEN [Tape] END) AS ' + QUOTENAME([Server]),
','
) WITHIN GROUP(ORDER BY [Server])
FROM
(
SELECT [Server] FROM T GROUP BY [Server]
) S;
SET #Sql =
'SELECT ' + #Columns + ' FROM
(SELECT [Server], [Tape], ROW_NUMBER() OVER (PARTITION BY [SERVER] ORDER BY [Server]) as RN FROM T) S
GROUP BY RN'
EXEC(#Sql);
Note: STRING_AGG() is supported on SQL Server 2017 and later.

Moving Column names to rows

I have such a table with date as column name
but I would like to have these dates in one column in more than one row something like this:
Date Index
20170806 9206
20170813 8041
20170820 8861
20170827 8356
How can I do it in SQL Server
If you would like to go for more dynamic solution rather than hard coding all columns, the below scripts should work:
IF OBJECT_ID('TestTable') IS NOT NULL
DROP TABLE TestTable;
CREATE TABLE TestTable
(
[20170806] INT NOT NULL,
[20170813] INT NOT NULL,
[20170820] INT NOT NULL,
[20170827] INT NOT NULL
)
INSERT INTO TestTable VALUES (9206, 8041, 8861, 8356)
DECLARE #cols NVARCHAR(MAX),
#sql NVARCHAR(MAX)
SELECT #cols = COALESCE(#cols + ',', '') + QUOTENAME(c.COLUMN_NAME)
FROM INFORMATION_SCHEMA.[COLUMNS] AS c
WHERE c.TABLE_NAME = 'TestTable'
SET #sql = '
SELECT [Date],
[Index]
FROM TestTable
UNPIVOT([Index] FOR [Date] IN ('+ #cols +')) AS up'
exec sp_executesql #sql;
You can use UNPIVOT for this.
SELECT * FROM MyTable
UNPIVOT([Date] For [Index] IN( [20170806], [20170813], [20170820], [20170827])) UNPVT
In addition, if you want to make it dynamically, you can use this query too.
DECLARE #ColNames NVARCHAR(MAX)
= STUFF(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
(SELECT T.* FROM (VALUES(1)) AS DUMY(ID) LEFT JOIN MyTable T ON 1=2 FOR XML AUTO, ELEMENTS XSINIL )
,'<T xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">','')
,'</T>','')
,'_x0032_','2')
,' xsi:nil="true"/>','] ')
,'<',',[') ,1,1,'')
DECLARE #SqlQ NVARCHAR(MAX)
= 'SELECT * FROM MyTable UNPIVOT([Date] For [Index] IN( ' + #ColNames + ')) UNPVT'
EXEC sp_executesql #SqlQ
You could use pivot such as:
However, i dont know your exact table names
select field_names
from table_name
pivot
( index
for index in ( Date, Index)
) pivot
but a useful article to follow is
"https://technet.microsoft.com/en-us/library/ms177410(v=sql.105).aspx"
Designed the table (variable) structure as below.
Hopefully, it matches your table structure.
DECLARE #data TABLE
(
[20170806] INT,
[20170813] INT,
[20170820] INT,
[20170827] INT
)
INSERT INTO #data VALUES (9206, 8041, 8861, 8356)
SELECT * FROM #data
You can use UNPIVOT statement for this. If you have dynamic columns, check this.
SELECT [Date],[Index]
FROM
#data
UNPIVOT
(
[Index] FOR [Date] IN ([20170806], [20170813], [20170820], [20170827])
) AS unpivotTable;
and the output is

Inserting dynamic pivot result into an existing table without knowing table definition

I have a dynamic pivot table that produces an unknown number of columns until runtime. I am trying to clear the data out of an existing table and insert the results of my query into it. The problem that I am having is that I do not know what the table definition will be ahead of time because it is dynamic.
Here is the error I am getting:
Msg 213, Level 16, State 7, Line 1
Column name or number of supplied values does not match table definition.
The pivoted column is a date column which could have 1 date or 1000+ dates.
How can I create a table definition that will match the data that I am trying to insert?
Here is my query:
DECLARE #colsPivot AS NVARCHAR(MAX),
#colsUnpivot AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #colsPivot = STUFF((SELECT ',' + QUOTENAME(rce.EcoDate)
from PhdRpt.RptCaseEco_542 AS rce
group by rce.EcoDate
order by rce.EcoDate
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
SELECT #colsUnpivot = stuff((SELECT ','+quotename(C.name)
FROM sys.columns AS C
WHERE C.object_id = object_id('PhdRpt.RptCaseEco_542') AND
C.name in ('NDCash', 'DCash')--LIKE '%Cash' or C.Name like 'NetGas'
FOR xml path('')), 1, 1, '')
set #query
= 'select *
--into ##hello
from
(
SELECT
ReportRunCaseId,
col,
EcoDate,
val
FROM PhdRpt.RptCaseEco_542
unpivot
(
val
for col in ('+ #colsunpivot +')
) u
) x1
pivot
(
max(val)
for EcoDate in ('+ #colspivot +')
) p'
truncate table dbo.Table1
insert into dbo.Table1
exec(#query)
I would DROP original table and just create new one on the fly using SELECT INTO clause.
by using SELECT INTO you do not need to create table before hand or worry what type and how many columns it will have. SQL Server will just create it for you.
Note: this only works when table does not exists.
Full documentation on INTO Clause http://technet.microsoft.com/en-us/library/ms188029.aspx
as another alternative you can always SELECT INTO #temp table that you can drop or use it to model your other table but I think this is extra work that you do not want to do.
You can do something like this:
DROP TABLE dbo.Table1
DECLARE #colsPivot AS NVARCHAR(MAX),
#colsUnpivot AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #colsPivot = STUFF((SELECT ',' + QUOTENAME(rce.EcoDate)
from PhdRpt.RptCaseEco_542 AS rce
group by rce.EcoDate
order by rce.EcoDate
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
SELECT #colsUnpivot = stuff((SELECT ','+quotename(C.name)
FROM sys.columns AS C
WHERE C.object_id = object_id('PhdRpt.RptCaseEco_542') AND
C.name in ('NDCash', 'DCash')--LIKE '%Cash' or C.Name like 'NetGas'
FOR xml path('')), 1, 1, '')
set #query
= 'select *
into dbo.Table1
from
(
SELECT
ReportRunCaseId,
col,
EcoDate,
val
FROM PhdRpt.RptCaseEco_542
unpivot
(
val
for col in ('+ #colsunpivot +')
) u
) x1
pivot
(
max(val)
for EcoDate in ('+ #colspivot +')
) p'
exec(#query)

Dynamic pivot table with multiple columns in sql server

I am trying to pivot table DYNAMICALLY but couldn't get the desired result.
Here is the code to create a table
create table Report
(
deck char(3),
Jib_in float,
rev int,
rev_insight int,
jib_out float,
creation int
)
insert into Report values
('A_1',0.345,0,0,1.23,20140212),
('B_2',0.456,0,4,2.34,20140215),
('C_3',0.554,0,6,0.45,20140217),
('D_4',0.231,0,8,7.98,20140222),
('E_5',0.453,0,0,5.67,20140219),
('F_6',0.344,0,3,7.23,20140223)'
Code written so far.... this pivots the column deck and jib_in into rows but thats it only TWO ROWS i.e the one i put inside aggregate function under PIVOT function and one i put inside QUOTENAME()
DECLARE #columns NVARCHAR(MAX), #sql NVARCHAR(MAX);
SET #columns = N'';
SELECT #columns += N', p.' + QUOTENAME(deck)
FROM (SELECT p.deck FROM dbo.report AS p
GROUP BY p.deck) AS x;
SET #sql = N'
SELECT ' + STUFF(#columns, 1, 2, '') + '
FROM
(
SELECT p.deck, p.jib_in
FROM dbo.report AS p
) AS j
PIVOT
(
SUM(jib_in) FOR deck IN ('
+ STUFF(REPLACE(#columns, ', p.[', ',['), 1, 1, '')
+ ')
) AS p;';
PRINT #sql;
EXEC sp_executesql #sql;
I need all the columns to be pivoted and show on the pivoted table. any help would be appreciated. I am very new at dynamic pivot. I tried so many ways to add other columns but no avail!!
I know there are other ways please feel free to mention if there is any other way to get this right.
Please use this (If you are getting Collation issue, please change all the 3 INT datatypes):
STATIC code:
SELECT HEADER, [A_1],[B_2],[C_3],[D_4],[E_5],[F_6]
FROM
(SELECT DECK,HEADER, VALUE FROM REPORT
UNPIVOT
(
VALUE FOR HEADER IN ([JIB_IN],[REV],[REV_INSIGHT],[JIB_OUT],[CREATION])
) UNPIV
) SRC
PIVOT
(
SUM(VALUE)
FOR DECK IN ([A_1],[B_2],[C_3],[D_4],[E_5],[F_6])
) PIV
Using Dynamic SQL:
DECLARE #COLSUNPIVOT AS NVARCHAR(MAX),
#QUERY AS NVARCHAR(MAX),
#COLSPIVOT AS NVARCHAR(MAX)
SELECT #COLSUNPIVOT = STUFF((SELECT ','+QUOTENAME(C.NAME)
FROM SYS.COLUMNS AS C
WHERE C.OBJECT_ID = OBJECT_ID('REPORT') AND C.NAME <> 'DECK'
FOR XML PATH('')), 1, 1, '')
SELECT #COLSPIVOT = STUFF((SELECT ',' + QUOTENAME(DECK)
FROM REPORT T FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)') ,1,1,'')
SET #QUERY
= 'SELECT HEADER, '+#COLSPIVOT+'
FROM
(
SELECT DECK,HEADER,VALUE FROM REPORT
UNPIVOT
(
VALUE FOR HEADER IN ('+#COLSUNPIVOT+')
) UNPIV
) SRC
PIVOT
(
SUM(VALUE)
FOR DECK IN ('+#COLSPIVOT+')
) PIV'
EXEC(#QUERY)

sql table row - column conversion

I have following table:
How to convert the above table into below structure? I tried using pivot table but couldn't get it to work.
You need to have to look up SQL PIVOT.
Check this fiddle
And the code:
SELECT *
FROM
(
SELECT Prodname,
pcode,
Biiledamt
FROM Product
) p
PIVOT
(
SUM (Biiledamt)
FOR Prodname IN ([Prod1],[Prod2],[Prod3],[Prod4])
) AS pvt
If you do not know beforehand the columns then you can check this fiddle which dynamically generates the columns to use.
The code for that is:
DECLARE #cols AS VARCHAR(MAX),
#query AS VARCHAR(MAX)
SET #cols = STUFF((SELECT distinct ',[' + Prodname +']'
FROM Product c
FOR XML PATH(''), TYPE
).value('.', 'VARCHAR(MAX)')
,1,1,'')
SET #query =
' SELECT *
FROM
(
SELECT Prodname,
pcode,
Biiledamt
FROM Product
) p
PIVOT
(
SUM (Biiledamt)
FOR Prodname IN (' + #cols + ')
) AS pvt
'
EXEC(#query)