Just learning SQL - I have the following table:
Site1 Totals
Status1 20
Status2 5
Status3 15
Status4 145
Status5 1
And need to convert the columns and rows, adding a new column name "Server Name" and changing the rows to columns, to return the following:
Server name Status1 Status2 Status3 Status4 Status5
Site1 20 5 15 145 1
Is anyone able to help with this?
Thankyou
select ServerName = 'Site1', *
from
(
select Totals, Site1
from Sometable
) d
pivot
(
max(Totals)
for Site1 in (Status1, Status2, Status3, Status4, Status5)
) piv;
EDIT:
If you need to dynamically load values from Site1 column you can do it this way:
CREATE table #yourtable
([Site1] varchar(20), [Totals] int)
;
INSERT INTO #yourtable
([Site1], [Totals])
VALUES
('Status1', 20),
('Status2', 45),
('Status3', 77),
('Status4', 55)
;
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT ',' + QUOTENAME(Site1)
from #yourtable
group by Site1
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = N'SELECT ServerName=''Site1'', ' + #cols + N' from
(
select Site1, Totals
from #yourtable
) x
pivot
(
max(Totals)
for Site1 in (' + #cols + N')
) p '
exec sp_executesql #query;
DEMO
Related
I have been able to successfully pivot different field values into separate columns but what I want is to concatenate all of those separate (pivoted) columns into one column. I don't know how many pivoted columns that I end up with at runtime so I can't just use Column1 + Column2 + Column3 etc.
Here is my sql
--Create a table variable to hold my source data
declare #datatable table
(
OrderId int,
ProductId int,
ClientName varchar(50)
)
--insert some data
insert into #datatable values (1, 2, 'Joe Bloggs')
insert into #datatable values (1, 2, 'Frank Bloggs')
--Create a temp table
--that introduces a new field (called Header)
--to give me column names for my pivoted data
IF OBJECT_ID('tempdb..#PivotedClients') IS NOT NULL DROP TABLE #PivotedClients
create table #PivotedClients
(
OrderId int,
ProductId int,
ClientName varchar(50),
Header varchar(100)
)
insert into #PivotedClients
select OrderId,
ProductId,
ClientName,
'Client ' + Cast(Rank() Over (Partition by OrderId
order by ClientName) as varchar(3))
from #datatable
--Create variables to hold my column names
--and my (dynamic) sql
declare #pivotcolumns nvarchar(max),
#colsWithNoNulls nvarchar(max),
#sqlquery nvarchar(max)
set #pivotcolumns = STUFF(
(
select distinct ',' + QUOTENAME(Header)
from #PivotedClients
for XML PATH (''), TYPE
).value('.', 'nvarchar(max)')
,1,1,'')
set #colsWithNoNulls = STUFF(
(
SELECT DISTINCT ',ISNULL(' + QUOTENAME(Header) + ', '''') ' + QUOTENAME(Header)
FROM #PivotedClients
for XML PATH (''), TYPE
).value('.', 'NVARCHAR(max)')
,1,1,''
)
if OBJECT_ID('tempdb..##Clients ') is not null drop TABLE ##Clients
set #sqlquery = 'select distinct OrderId,
ProductID,
' + #colsWithNoNulls + '
into ##Clients
from
(
select OrderId,
ClientName,
ProductID,
Header
from #PivotedClients) x
pivot
(
Max(ClientName)
for Header in (' + #pivotcolumns + ')
) p'
exec sp_executesql #sqlquery
----
select *
from ##Clients
----
The record set that I currently end up with is:
OrderId ProductId Client1 Client 2
1 2 Frank Bloggs Joe Blogs
What I want is:
OrderID ProductId Clients
1 2 Frank Bloggs Joe Bloggs
I don't know how many 'pivoted' columns that I will end up with at runtime so I can't just use Client1 + Client2 etc
Just need to change your #colsWithNoNulls to perform the string concatenation
set #colsWithNoNulls = STUFF(
(
SELECT DISTINCT '+ '' '' + ISNULL(' + QUOTENAME(Header) + ', '''')'
FROM #PivotedClients
for XML PATH (''), TYPE
).value('.', 'NVARCHAR(max)')
, 1, 1, '') + 'AS Clients'
Also you can do a print #sqlquery before sp_executesql. this will helps you debug your dynamic query
I have a table with around 10 rows. I want to pivot on all values in one column to a one-row multi column result. It looks as though there is no way to get around the "For ContactTypeID in ([1],[2])" syntax.
ContactTypeID int
ContactType varchar(20)
Sample data:
1 Customer
2 Vendor
...
5 BillTo
I want to return a single row with
Customer Vendor BillTo, etc
1 2 5
But like I said, I don't want to have to specify each ContactTypeID by number. Is there way to specify "for all"?
Thank you.
You need a dynamic pivot.
Here's the code, for your reference. Hope it helps.
CREATE TABLE tablename (ContactTypeID int, ContactType varchar(20));
INSERT INTO tablename VALUES (1, 'Customer'), (2, 'Vendor'), (5, 'BillTo');
DECLARE #cols NVARCHAR (MAX);
SELECT #cols = COALESCE (#cols + ',[' + ContactType + ']',
'[' + ContactType + ']')
FROM (SELECT DISTINCT [ContactType] FROM tablename) PV
ORDER BY [ContactType]
DECLARE #query NVARCHAR(MAX)
SET #query = '
SELECT * FROM
(
SELECT * FROM tablename
) x
PIVOT
(
MIN(ContactTypeID)
FOR [ContactType] IN (' + #cols + ')
) p
'
EXEC SP_EXECUTESQL #query;
Query:
select employee_sk,
[201701],
[201702]
from
(select Employee_SK, Period_NK, CalcClinical_FTE from cmgr.FACT_Payroll) as sourcetable
pivot
(
sum(CalcClinical_FTE)
for period_nk
in ([201701],[201702])
) as a
I have multiple periods in the period_nk column ranging from 201401 to 201801.
So, how can i assign the pivot values without having to write each column individually like 201701,201702, 201703...?
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX);
SET #cols = STUFF((SELECT distinct ',' + QUOTENAME(c.period_nk)
FROM temp c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT category, ' + #cols + ' from
(
select category,
period_nk,
amount
from temp
) x
pivot
(
max(amount)
for period_nk in (' + #cols + ')
) p '
execute(#query)
drop table temp
Output :
category 201701 201702 201703 201704 201705
1 ABC 1000,0000 NULL NULL NULL 1100,0000
2 DEF NULL 500,0000 NULL 700,0000 NULL
3 GHI NULL NULL 800,0000 NULL NULL
online demo
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