CREATE TABLE TEMP (
DATE DATETIME
,category VARCHAR(3)
,amount MONEY
,NAMES VARCHAR(5)
)
INSERT INTO TEMP
VALUES (
'1/1/2012'
,'ABC'
,1000.00
,'john'
)
INSERT INTO TEMP
VALUES (
'2/1/2012'
,'DEF'
,500.00
,'amy'
)
INSERT INTO TEMP
VALUES (
'2/1/2012'
,'GHI'
,800.00
,'blue'
)
INSERT INTO TEMP
VALUES (
'2/10/2012'
,'DEF'
,700.00
,'ivy'
)
INSERT INTO TEMP
VALUES (
'3/1/2012'
,'ABC'
,1100.00
,'mark'
)
DECLARE #cols1 AS NVARCHAR(MAX)
,#cols2 AS NVARCHAR(MAX)
,#query AS NVARCHAR(MAX);
SET #cols1 = STUFF((
SELECT DISTINCT ',' + QUOTENAME(c.category)
FROM TEMP c
FOR XML PATH('')
,TYPE
).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
SET #cols2 = STUFF((
SELECT DISTINCT ',' + QUOTENAME(c.NAMES)
FROM TEMP c
FOR XML PATH('')
,TYPE
).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
--select #cols
SET #query = 'SELECT date, ' + #cols1 + #cols2 + ' from
(
select date
, amount
, category
, names
from temp
) x
pivot
(
max(amount)
for category in (' + #cols1 + ')
) p
pivot
(
max(amount)
for names in (' + #cols2 + ')
) p
'
EXEC (#query)
Drop table temp
Below is the result I'm trying to get but I get an error Invalid column name 'amount'
ABC DEF GHI John Amy Blue Ivy Mark
1/1/2012 1000 NULL NULL 1000 NULL NULL NULL NULL
2/1/2012 NULL 500 NULL NULL 500 NULL NULL NULL
2/1/2012 NULL NULL 800 NULL NULL 800 NULL NULL
2/10/2012 NULL 700 NULL NULL NULL NULL 700 NULL
3/1/2012 1100 NULL NULL NULL NULL NULL NULL 1100
You can try the below query.
CREATE TABLE TEMP (
DATE DATETIME
,category VARCHAR(3)
,amount MONEY
,NAMES VARCHAR(5)
)
INSERT INTO TEMP
VALUES (
'1/1/2012'
,'ABC'
,1000.00
,'john'
)
INSERT INTO TEMP
VALUES (
'2/1/2012'
,'DEF'
,500.00
,'amy'
)
INSERT INTO TEMP
VALUES (
'2/1/2012'
,'GHI'
,800.00
,'blue'
)
INSERT INTO TEMP
VALUES (
'2/10/2012'
,'DEF'
,700.00
,'ivy'
)
INSERT INTO TEMP
VALUES (
'3/1/2012'
,'ABC'
,1100.00
,'mark'
)
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX);
SET #cols = STUFF((SELECT distinct ',' + QUOTENAME(c.category)
FROM temp c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT date, ' + #cols + ' from
(
select date
, amount
, category
from temp
) x
pivot
(
max(amount)
for category in (' + #cols + ')
) p '
execute(#query)
You can't use pivot like that, you need to pivot the data separately.
A quick way to get what you want would be:
WITH Table1 AS
(
SELECT date, [ABC],[DEF],[GHI]
from
(
select date
, amount
, category
, names
from temp
) AS x
pivot
(
MAX(Amount)
for category in ([ABC],[DEF],[GHI])
) AS A
)
,Table2 AS
(
SELECT date, [amy],[blue],[ivy],[john],[mark]
from
(
select date
, amount
, category
, names
from temp
) AS x
pivot
(
max(amount)
for names in ([amy],[blue],[ivy],[john],[mark])
) AS B
)
SELECT *
FROM Table1 A
INNER JOIN Table2 B on A.date = B.date;
Hope you got your result from this query.
CREATE TABLE #TEMP (DATE DATETIME,category VARCHAR(3),amount MONEY,NAMES VARCHAR(5))
INSERT INTO #TEMP VALUES ('3/1/2012','ABC',1100.00,'mark')
INSERT INTO #TEMP VALUES ('1/1/2012','ABC',1000.00,'john')
INSERT INTO #TEMP VALUES ('2/10/2012','DEF',700.00,'ivy')
INSERT INTO #TEMP VALUES ('2/1/2012','DEF',500.00,'amy')
INSERT INTO #TEMP VALUES ('2/1/2012','GHI',800.00,'blue')
select * into #Category from (-----CREATE PIVOT BASED ON CATEGORY FROM #TEMP TABLE AND INSERT DATA INTO #CATEGORY TABLE
select * from #TEMP
) as t1
pivot (sum(amount) for Category IN ([ABC],[DEF],[GHI])) AS CategoryAmount
select * into #Names from (-----CREATE PIVOT BASED ON NAMES FROM #TEMP TABLE AND INSERT DATA INTO #Names TABLE
select * from #TEMP
) as t1
pivot (sum(amount) for names IN ([amy],[blue],[ivy],[john],[mark])) AS CategoryAmount
--HERE IS YOUR FINAL QUERY WHERE YOU GOT YOUR RESULT AS PER YOUR REQUIREMENT
select c.DATE,SUM(c.ABC) ABC,SUM(c.DEF) DEF,SUM(c.GHI) GHI,SUM(n.John) JOHN,SUM(n.Amy) AMY,SUM(n.Blue) BLUE,SUM(n.Ivy) IVY,SUM(n.Mark) MARK from #Category C
inner join #Names n on c.DATE = n.DATE
GROUP BY C.DATE
drop table #TEMP,#Category,#Names
Related
I have a query with this result:
And I tried this query to make a pivot
with T as (
select pwv.PayrollMovementHeaderId as HeaderId,
CONCAT(w.PaternalSurname, w.PaternalSurname, w.Name) as Worker,
pv.Code as Code,
pwv.Value
from PayrollWorkerVariables pwv
join PayrollVariables pv on pv.Id = pwv.PayrollVariableId
join Workers w on w.Id = pwv.WorkerId
) select * from T Pivot ( Value For Code in ([T01],[T02])) as pvt
what I need is this result
HeaderId - Worker - T01 - T02 ..... - Tn
-----------------------------------------
aaaaaaaa - bbbbbb - Val - Val
You can use the pivot like the following:
create table #t (HeaderId varchar(100), Worker varchar(100), Code varchar(10), [Value] varchar(100))
insert into #t select 'aaaaaa', 'bbbbb', 'T01', '49.7'
insert into #t select 'aaaaaa', 'bbbbb', 'T25', '1'
insert into #t select 'aaaaaa', 'bbbbb', 'T02', '0'
insert into #t select 'aaaaaa', 'bbbbb', 'T13', 'False'
insert into #t select 'aaaaaa', 'bbbbb', 'T08', '0.0'
insert into #t select 'aaaaaa', 'bbbbb', 'T04', '2'
insert into #t select 'aaaaaa', 'bbbbb', 'T06', 'RI'
insert into #t select 'aaaaaa', 'bbbbb', 'T07', 'True'
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX);
SET #cols = STUFF((SELECT distinct ',' + QUOTENAME(t.Code)
FROM #t t
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT HeaderId, Worker, ' + #cols + ' from
(
select HeaderId, Worker, Code, [Value]
from #t
) x
pivot
(
max([Value]) for Code in (' + #cols + ')
) p '
print (#query)
execute(#query)
Please find the demo here.
I have the following schema and sample data.
create table MyTable
(
Id int,
Year int,
Channel varchar(10),
Payments int
)
insert into MyTable values
(1,2012,'HV',100),
(1,2014,'HV',56),
(2,2012,'NL',17000)
(2,2012,'HV',495),
(3,2013,'HV',565)
Now I want to create and insert dynamic pivot data in a temporary table. I am able to create the pivot data as the demo here.
But I want to store this data into a temporary table. What I have tried is as below.
Declare #SQL varchar(max) = '
if object_id(''tempdb..##TempTable'') is not null
begin
drop table ##TempTable
end
create table ##TempTable([Id] int null, ' +
Stuff((Select Distinct ','+QuoteName(Channel + CONVERT(Varchar(4), Year)) + ' Varchar(20) null'
From [dbo].MyTable
Order By 1
For XML Path('')),1,1,'')+ ')
INSERT INTO ##TempTable
Select *
From (
Select A.Id
,B.*
From [dbo].[MyTable] A
Cross Apply ( values ( Id, Channel + CONVERT(Varchar(4), Year)
)) B (Item,Value)
) S
Pivot (sum([Payments]) For Channel + CONVERT(Varchar(4), Year) in
(' + Stuff((Select Distinct ','+QuoteName(Channel + CONVERT(Varchar(4), Year))
From [dbo].MyTable
Order By 1
For XML Path('')),1,1,'') + ') ) p'
select #SQL
Exec(#SQL);
SELECT * FROM ##TempTable
It is giving me the following error.
Msg 102, Level 15, State 1, Line 18 Incorrect syntax near '+'.
When printing the dynamic query it is giving the following result.
if object_id('tempdb..##TempTable') is not null
begin
drop table ##TempTable
end
create table ##TempTable([Id] int null, [HV2012] Varchar(20) null,[HV2013] Varchar(20) null,[HV2014] Varchar(20) null,[NL2012] Varchar(20) null)
INSERT INTO ##TempTable
Select * From ( Select A.Id ,B.* From [dbo].[MyTable] A
Cross Apply ( values ( Id, Channel + CONVERT(Varchar(4), Year) )) B (Item,Value) ) S
Pivot (sum([Payments]) For Channel + CONVERT(Varchar(4), Year) in ([HV2012],[HV2013],[HV2014],[NL2012]) ) p
If you are using apply then why you need further same logic in PIVOT (i.e. Channel + CONVERT(Varchar(4), Year)) which is already available in apply.
So, i would use Value instead in PIVOT :
. . .
Pivot (sum([Payments]) For [Value] in ([HV2012],[HV2013],[HV2014],[NL2012]) ) p,
So, your updated Dynamic SQL would be :
Declare #SQL varchar(max) = '
if object_id(''tempdb..##TempTable'') is not null
begin
drop table ##TempTable
end
create table ##TempTable([Id] int null, ' +
Stuff((Select Distinct ','+QuoteName(Channel + CONVERT(Varchar(4), Year)) + ' Varchar(20) null'
From [dbo].MyTable
Order By 1
For XML Path('')),1,1,'')+ ')
INSERT INTO ##TempTable
Select *
From (
Select A.ID, A.Payments
,B.*
From [dbo].MyTable a
Cross Apply ( values ( Channel + CONVERT(Varchar(4), Year)
)) B ([Value])
) S
Pivot (sum([Payments]) For [Value] in
(' + Stuff((Select Distinct ','+QuoteName(Channel + CONVERT(Varchar(4), Year))
From #tm
Order By 1
For XML Path('')),1,1,'') + ') ) p'
print #sql
Exec(#SQL)
SELECT * FROM ##TempTable
I have made no of changes as there are many correction needs to be done prior to execution.
hello friends i m trying to convert row Data with dates in column headers
this is my sql attendanceData Table
Normal Table
Original Data
and i want to convert row dates into column headers like this
Transpose
can someone tell me how i can do this in sql
i m sure using pivot i can,
so i tried sql query to pivot
SELECT Enterprise_ID, Date, Attendance
FROM attendanceData natural
join ( SELECT Enterprise_ID
FROM attendanceData
group BY Enterprise_ID
)
pivot (max(P) for Attendance in ('P' as P, 'WO' as WO)
I tried using dynamic pivot
Sample script to generate data:
create table #a
(
entrprise_id varchar(50),
datee date,
attendance varchar(10)
)
insert into #a values
('james','2018-12-22','p'),
('james','2018-12-23','p'),
('pick','2018-12-23','p'),
('rick','2018-12-23','p'),
('pick','2018-12-22','p'),
('rick','2018-12-22','p')
PIVOT Query:
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX);
SET #cols = STUFF((SELECT distinct ',' + QUOTENAME(c.datee)
FROM #a c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT entrprise_id, ' + #cols + ' from
(
select*
from #A
) x
pivot
(
max(attendance)
for datee in (' + #cols + ')
) p '
execute(#query)
or
select *
from
(
select *
from #A
) src
pivot
(
max(attendance)
for datee in ([2018-12-22], [2018-12-23])
) piv
i have 3 table PhoneBook, DynamicField, PhoneBook_DynamicField_Rel
PhoneBook :
|---ID----|---Name----|
1 Reza
2 Ali
DynamicField :
|---ID----|--Caption--|
1 Job
2 Level
PhoneBook_DynamicField_Rel:
|---ID----|--PhoneBookID--|--DynamicFieldID--|---Value---|
1 1 1 Emp
2 1 2 1
3 2 1 SomeJob
i want execute query with this result :
|--PhoneBookID--|--Name--|--Job--|--Level--|
1 Reza Emp 1
2 Ali SomeJob NULL
Maybe something like this:
Test data:
CREATE TABLE #PhoneBook(ID INT,Name VARCHAR(100))
INSERT INTO #PhoneBook VALUES(1,'Reza'),(2,'Ali')
CREATE TABLE #DynamicField(ID INT,Caption VARCHAR(100))
INSERT INTO #DynamicField VALUES(1,'Job'),(2,'Level')
CREATE TABLE #PhoneBook_DynamicField_Rel(ID INT,PhoneBookID INT,
DynamicFieldID INT,Value VARCHAR(100))
INSERT INTO #PhoneBook_DynamicField_Rel
VALUES(1,1,1,'Emp'),(2,1,2,'1'),(3,2,1,'SomeJob')
Getting the colums
DECLARE #cols VARCHAR(MAX)
SELECT #cols=STUFF
(
(
SELECT
',' +QUOTENAME(tbl.Caption)
FROM
#DynamicField AS tbl
FOR XML PATH('')
)
,1,1,'')
Then the query like this:
DECLARE #query NVARCHAR(4000)=
N'SELECT
*
FROM
(
SELECT
*
FROM
(
SELECT
PhoneBook.ID,
PhoneBook.Name,
field.Caption,
rel.Value
FROM
#PhoneBook AS PhoneBook
JOIN #PhoneBook_DynamicField_Rel AS rel
ON PhoneBook.ID = rel.PhoneBookID
JOIN #DynamicField AS field
ON rel.DynamicFieldID=field.ID
) AS SourceTable
) AS p
PIVOT
(
MAX(Value) FOR Caption IN('+#cols+')
) AS pvt'
EXECUTE(#query)
Then in my case I will drop the temp tables:
DROP TABLE #PhoneBook
DROP TABLE #DynamicField
DROP TABLE #PhoneBook_DynamicField_Rel
What you need is dynamic pivot:
declare #collist nvarchar(max)
SET #collist = stuff((select distinct ',' + QUOTENAME(caption)
FROM DynamicField
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
declare #q nvarchar(max)
set #q = '
select PhoneBookID, Name, ' + #collist + '
from (
select PhoneBookID, Name, Caption, Value
from (
select PhoneBookID, Name, Caption, Value
from PhoneBook pb
inner join PhoneBook_DynamicField_Rel pbdf on pb.ID = pbdf.PhoneBookID
inner join DynamicField df on df.ID = pbdf.DynamicFieldID
) as x
) as source
pivot (
max(Value)
for caption in (' + #collist + ')
) as pvt
'
exec (#q)
i want to create a query from multiple records as one record , but i don't want to use Pivot, is there any solutions?
here's the table :
ID Element_Name Value
1 Parmitha 100
2 Anggun 200
3 Chandra 300
4 BagusofTerror 400
and i want the result is like this :
paramitha , anggun, chandra , bagusofterror
100 , 200, 300, 400
You can use for xml path ('') to transpose the values of a column.
For example, you could write
select Element_Name + ', '
from TheTable
for xml path ('');
To get Parmitha, Anggun, Chandra, BagusofTerror,
Here's a live demo: http://www.sqlfiddle.com/#!3/71f88/24
You can also use COALESCE to pivot a results set of columns into a varchar variable:
CREATE TABLE #Pivot
(ID int, Element_Name varchar(50), Value int)
INSERT #Pivot values (1,'Parmitha',100)
INSERT #Pivot values (2,'Anggun',200)
INSERT #Pivot values (3,'Chandra',300)
INSERT #Pivot values (4,'BagusofTerror',400)
DECLARE #titles VARCHAR(1000)
DECLARE #values VARCHAR(1000)
SET #titles = ''
SET #values = ''
SELECT #titles = #titles + COALESCE(Element_Name + ',' , '')
FROM #Pivot ORDER BY ID
SELECT #values = #values + COALESCE(convert(varchar, Value) + ',' , '')
FROM #Pivot ORDER BY ID
SELECT #titles
UNION ALL
SELECT #values
Gives:
Parmitha,Anggun,Chandra,BagusofTerror,
100,200,300,400,
Try this :-
Select
MAX(CASE WHEN colID = 1 THEN value ELSE NULL END) AS [Parmitha],
MAX(CASE WHEN colID = 2 THEN value ELSE NULL END) AS [Anggun],
MAX(CASE WHEN colID = 3 THEN value ELSE NULL END) AS [Chandra],
MAX(CASE WHEN colID = 4 THEN value ELSE NULL END) AS [BagusofTerror]
FROM
(
SELECT ROW_NUMBER() OVER (ORDER BY ID) AS colID,
ID,
Element_Name,
value
FROM Sample
) AS d
SQL DEMO
Taking Wolf's answer into consideration ,using dynamic query and xml path
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT distinct ','
+ convert(varchar(max), Element_Name, 120)
from Sample
FOR XML PATH(''), TYPE
).value('.', 'varchar(MAX)')
,1,1,'')
set #query = 'SELECT' + #cols + ' from
(
select value, Element_Name
from Sample
) x
pivot
(
max(value)
for Element_Name in (' + #cols + ')
) p '
execute(#query);
Demo
By the way y don't u use PIVOT .Using PIVOT the same result can be achieved
Select [Parmitha],[Anggun],[Chandra],[BagusofTerror]
FROM
(
Select value,element_name from Sample
)src
pivot
(
max(value)
for Element_Name in ([Parmitha],[Anggun],[Chandra],[BagusofTerror])
)pvt