SQL to convert distinct item in row to column - sql

I have a table as
Date Item Quantity
20170101 Mango 5
20170101 Orange 6
20170102 Mango 7
20170102 Orange 8
I want below output
Date Mango Orange
20170101 5 6
20170102 7 8
for this i used below sql query
SELECT
Date,
SUM(case when Item='Mango' then Quantity else 0 end) AS Mango,
SUM(case when Item='Orange' then Quantity else 0 end) AS Orange
FROM orderTable
GROUP BY date
but this is kind of hard coding for Mango and Orange. What if I need new item in orderTable. Can any one suggest me how can I make this query dynamic. So that if I add new item it automatically create new coulmn having item name as name and it will have 0 value under column against date when order not placed for that item.
like
Date Item Quantity
20170101 Mango 5
20170101 Orange 6
20170102 Mango 7
20170102 Orange 8
20170102 Cherry 9
then output should be as ...
Date Mango Orange Cherry
20170101 5 6 0
20170102 7 8 9

IF OBJECT_ID('Test') IS NOt NUll
DROP TABLE Test
CREATE TABLE Test
(
Date VARCHAR(100),
Item VARCHAR(100),
Quantity INT
)
INSERT Test VALUES
('20170101', 'Mango', 5),
('20170101', 'Orange', 6),
('20170102', 'Mango', 7),
('20170102', 'Orange', 8),
('20170102', 'Cherry', 9)
DECLARE #SQL AS VARCHAR(MAX)
DECLARE #Columns AS VARCHAR(MAX)
DECLARE #Columns2 AS VARCHAR(MAX)
SELECT #Columns = COALESCE(#Columns + ',','') + QUOTENAME(Item)
FROM (SELECT DISTINCT Item FROM Test) AS B
ORDER BY B.Item
SELECT #Columns2 = COALESCE(#Columns2 + ',','') + 'ISNULL(' + QUOTENAME(Item) + ', 0) AS ' + Item
FROM (SELECT DISTINCT Item FROM Test) AS B
ORDER BY B.Item
SET #SQL = '
WITH PivotData AS
(
SELECT Date, Item, Quantity FROM Test
)
SELECT
Date, ' + #Columns2 + '
FROM PivotData
PIVOT
(
SUM(Quantity)
FOR Item
IN (' + #Columns + ')
) AS PivotResult
ORDER BY Date'
EXEC(#SQL);
DROP TABLE Test
Result:
Date Cherry Mango Orange
20170101 0 5 6
20170102 9 7 8
Reference (code pic not shown but you can access it if you view source the page) :
http://sqlmag.com/t-sql/pivoting-dynamic-way

IF OBJECT_ID('Tempdb..#Temp') IS NOt NUll
Drop Table #Temp
;With cte([Date] ,Item ,Quantity)
AS
(
SELECT '20170101','Mango' ,5 Union all
SELECT '20170101','Orange' ,6 Union all
SELECT '20170102','Mango' ,7 Union all
SELECT '20170102','Orange' ,8 Union all
SELECT '20170102','Cherry' ,9
)
SELECT * INTO #Temp FROM cte
DECLARE #dynamicCol nvarchar(max),
#Sql nvarchar(max),
#dynamicCol2 nvarchar(max)
SELECT #dynamicCol=STUFF((SELECT DISTINCT ', ' + 'ISNULL('+Item +',''0'') AS '+ Item FROM #Temp
FOR XML PATH('')),1,1,'')
SELECT #dynamicCol2=STUFF((SELECT DISTINCT ', ' + Item FROM #Temp
FOR XML PATH('')),1,1,'')
SET #Sql='
SELECT [Date] , '+ #dynamicCol +' From
(
SELECT [Date] ,Item ,Quantity From
#temp
)AS Src
PIVOT
(
MAX([Quantity]) For [Item ] IN ('+#dynamicCol2+')
)
AS Pvt
'
PRINT #Sql
EXEC(#Sql)
OutPut
Date Cherry Mango Orange
----------------------------------
20170101 0 5 6
20170102 9 7 8

DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX);
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(c.Item)
FROM dbo.OrderTable c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT DateOrdered, ' + #cols + ' from
(
select Item, DateOrdered, Quantity
from dbo.OrderTable
) x
pivot
(
Sum(Quantity)
for Item in (' + #cols + ')
) p '
execute(#query)
If you do this it will give you result that you want

Try this :
CREATE TABLE [dbo].[test](
[Date] [int] NULL,
[Item] [nvarchar](50) NULL,
[Quantity] [int] NULL
) ON [PRIMARY]
GO
INSERT [dbo].[test] ([Date], [Item], [Quantity]) VALUES (20170101, N'Mango', 5)
GO
INSERT [dbo].[test] ([Date], [Item], [Quantity]) VALUES (20170101, N'Orange', 6)
GO
INSERT [dbo].[test] ([Date], [Item], [Quantity]) VALUES (20170102, N'Mango', 7)
GO
INSERT [dbo].[test] ([Date], [Item], [Quantity]) VALUES (20170102, N'Orange', 8)
GO
INSERT [dbo].[test] ([Date], [Item], [Quantity]) VALUES (20170102, N'Cherry', 5)
GO
INSERT [dbo].[test] ([Date], [Item], [Quantity]) VALUES (20170103, N'Cherry', 2)
GO
dynamic sql :
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT DISTINCT ',' + QUOTENAME(Item)
from test
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = N'SELECT DATE, ' + #cols + N' from
(
select Date,Item, Quantity from test
) x
pivot
(
max(Quantity)
for Item in (' + #cols + N')
) p '
exec sp_executesql #query;
result :
DATE Cherry Mango Orange
20170101 NULL 5 6
20170102 5 7 8
20170103 2 NULL NULL

Related

SQL Pivot Query with aggregation & Total

Table-A
ProductId
BrandName
1
Brand-1
2
Brand-2
3
Brand-3
Table-B
DCDate
DCNo
ProductId
Weight
2021-03-09
3
1
12.5
2021-03-09
3
1
12.6
2021-03-09
3
1
12.5
2021-03-09
3
2
10.5
2021-03-09
3
2
10.4
2021-03-09
3
3
15.5
2021-03-09
1
1
12.5
2021-03-09
1
3
15.7
2021-03-09
2
2
10.6
2021-03-09
4
1
12.7
2021-03-09
4
1
12.6
Expected Result:-
BrandName
1
2
3
4
Brand-1
1
0
3
2
Brand-2
0
1
2
0
Brand-3
1
0
1
0
Need Dynamic Pivot Query
What i tried
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT ',' + QUOTENAME([DCNo]) from [Table-B] FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)') ,1,1,'')
set #query = 'SELECT ' + #cols + '
from
(
SELECT a.[DCNo] , b.[BrandName], count(*) as Total FROM [Table-B] a inner join [Table-A] b on a.[ProductID]=b.[ProductID] group by [DCNo] , b.[BrandName] order by DCNo, b.[BrandName]
) x
pivot
(
max(Total)
for DCNo in (' + #cols + ')
) p '
execute(#query)
I've recreated it in a sqlfiddle: http://sqlfiddle.com/#!18/d1554/9 .
You were close but I sometimes find it easier to move all sum/count/grouping logic to the PIVOT section of the query instead. Results in simpler queries (most of the times)
CREATE TABLE [Table-A] (
ProductId INT,
BrandName VARCHAR(50)
)
CREATE TABLE [Table-B](
DCDate DATETIME,
DCNo INT,
ProductId INT,
Weight DECIMAL
)
INSERT INTO [Table-A] VALUES
(1, 'CAT'),
(2, 'APPLE'),
(3, 'PARROT')
INSERT INTO [Table-B] VALUES
('2021-03-09', 3, 1, 12.5),
('2021-03-09', 3, 1, 12.6),
('2021-03-09', 3, 1, 12.5),
('2021-03-09', 3, 2, 10.5),
('2021-03-09', 3, 2, 10.4),
('2021-03-09', 3, 3, 15.5),
('2021-03-09', 1, 1, 12.5),
('2021-03-09', 1, 3, 15.7),
('2021-03-09', 2, 2, 10.6),
('2021-03-09', 4, 1, 12.7),
('2021-03-09', 4, 1, 12.6)
-- Query
DECLARE #cols AS NVARCHAR(MAX) = '';
DECLARE #nullcols AS NVARCHAR(MAX) = '';
DECLARE #query AS NVARCHAR(MAX);
-- Determine columns
;WITH cte AS (
SELECT
DISTINCT
dcno,
',' + QUOTENAME([DCNo]) AS col,
', ISNULL(' + QUOTENAME([DCNo]) + ', 0) AS ' + QUOTENAME([DCNo]) AS nullcol
FROM [Table-B]
)
SELECT
#cols += col,
#nullcols += nullcol
FROM cte
ORDER BY dcno
SET #cols = SUBSTRING(#cols, 2, LEN(#cols))
-- create query
SET #query = N';with CTE AS
(
SELECT
a.BrandName,
a.ProductId,
b.DCNo,
1 as Value
FROM [Table-A] a
INNER JOIN [Table-B] b
ON a.ProductId = b.ProductId
)
SELECT BrandName ' + #nullcols + ' FROM
(SELECT * FROM cte) p
PIVOT
(
SUM(Value)
FOR DCNo IN (' + #cols + ')
) AS pvt
ORDER BY pvt.ProductId
'
-- SELECT #query
execute(#query)

Pivot with row wise Sum in SQL Server [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
TABLE-A:
PID
BrandName
1
Brand1
2
Brand2
3
Brand3
4
Brand4
5
Brand5
6
Brand6
7
Brand7
8
Brand8
TABLE-B:
CustNo
Name
BrandName
Qty
Amt
1
C1
Brand1
3
300
1
C1
Brand2
2
400
1
C1
Brand4
1
300
1
C1
Brand5
2
100
2
C2
Brand1
2
200
2
C2
Brand3
1
200
3
C3
Brand2
1
300
3
C3
Brand7
3
150
Expected Result:-
CustNo
Name
Brand1
Brand2
Brand3
Brand4
Brand5
Brand6
Brand7
Brand8
Amt
1
C1
3
2
0
1
2
0
0
0
1100
2
C2
2
0
1
0
0
0
0
0
400
3
C3
0
1
0
0
0
0
3
0
450
Pivot I tried:-
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT ',' + QUOTENAME(BrandName) from [TABLE-A] order by PID FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)') ,1,1,'')
set #query = 'SELECT CustNo,[Name],' + #cols + '
from
(
select CustNo,[Name],Qty,SUM(cast([amt] as float)) as Amt,BrandName from [TABLE-B] group by CustNo,[Name],BrandName,Qty
) x
pivot
(
max(Qty)
for brandname in (' + #cols + ')
) p '
execute(#query)
There are few things wrong in your query. First of all you selected column 'Slab' which is not in your table (might by due to copy from another query) Instead you need to select custno and name.
Then your query will run but you will have three rows for for each customer since each customer has three distinct value in quantity field. The reason behind is the group by clause (group by CustNo,[Name],BrandName,Qty) in inner query. Instead I have used window function to sum(amt) for each customer.
I have also used two set of dynamic column names to get rid of null value in the result. One to pivot as you used in your code (#cols) and other list contains coalesce(columnname,0) to convert null into 0.
And if you are using SQL Server 2017 and onward version then I would suggest to use string_agg() to concatenate the column names since it's easier and faster in performance. I have used it in Query#2.
Schema and insert statement:
create table [Table-A](PID int, BrandName varchar(50));
insert into [Table-A] values(1 ,'Brand1');
insert into [Table-A] values(2 ,'Brand2');
insert into [Table-A] values(3 ,'Brand3');
insert into [Table-A] values(4 ,'Brand4');
insert into [Table-A] values(5 ,'Brand5');
insert into [Table-A] values(6 ,'Brand6');
insert into [Table-A] values(7 ,'Brand7');
insert into [Table-A] values(8 ,'Brand8');
create table [TABLE-B]( CustNo int,Name varchar(10),BrandName varchar(50),Qty int, Amt int);
insert into [TABLE-B] values(1 ,'C1', 'Brand1', 3, 300);
insert into [TABLE-B] values(1 ,'C1', 'Brand2', 2, 400);
insert into [TABLE-B] values(1 ,'C1', 'Brand4', 1, 300);
insert into [TABLE-B] values(1 ,'C1', 'Brand5', 2, 100);
insert into [TABLE-B] values(2 ,'C2', 'Brand1', 2, 200);
insert into [TABLE-B] values(2 ,'C2', 'Brand3', 1, 200);
insert into [TABLE-B] values(3 ,'C3', 'Brand2', 1, 300);
insert into [TABLE-B] values(3 ,'C3', 'Brand7', 3, 150);
Query#1 (using stuff() and xml path for())
DECLARE #cols AS NVARCHAR(MAX),
#colsForSelect AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
SET #colsForSelect = STUFF((SELECT ',' + ' Coalesce('+quotename(BrandName)+',0) '+ quotename(BrandName)
FROM [TABLE-A] order by pid
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
select #cols = STUFF((SELECT ',' + QUOTENAME(BrandName) from [TABLE-A] order by PID FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)') ,1,1,'')
set #query = 'SELECT custno,name,' + #colsForSelect + ',Amt
from
(
select CustNo,[Name],Qty,SUM(cast([amt] as float))over(partition by custno) as Amt,BrandName from [TABLE-B] ) x
pivot
(
max(Qty)
for brandname in (' + #cols + ')
) p '
execute(#query)
Output:
custno
name
Brand1
Brand2
Brand3
Brand4
Brand5
Brand6
Brand7
Brand8
Amt
1
C1
3
2
0
1
2
0
0
0
1100
2
C2
2
0
1
0
0
0
0
0
400
3
C3
0
1
0
0
0
0
3
0
450
Query#2 (using string_agg() instead of stuff() and for xml path())
DECLARE #cols AS NVARCHAR(MAX),
#colsForSelect AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #colsForSelect= string_agg('coalesce('+BrandName+',0) '+QUOTENAME(BrandName)+' ',' ,') from [TABLE-A]
select #cols = string_agg(QUOTENAME(BrandName),',') from [TABLE-A]
set #query = 'SELECT custno,name,' + #colsForSelect + ',Amt
from
(
select CustNo,[Name],Qty,SUM(cast([amt] as float))over(partition by custno) as Amt,BrandName from [TABLE-B] ) x
pivot
(
max(Qty)
for brandname in (' + #cols + ')
) p'
execute(#query)
Output:
custno
name
Brand1
Brand2
Brand3
Brand4
Brand5
Brand6
Brand7
Brand8
Amt
1
C1
3
2
0
1
2
0
0
0
1100
2
C2
2
0
1
0
0
0
0
0
400
3
C3
0
1
0
0
0
0
3
0
450
db<>fiddle here

Order by in Pivot Column not in Result

Table-A
Productid
Brandname
1
C Brand
2
K Brand
3
A Brand
Table-B
Productid
Rate
Slab
1
10
1
2
20
1
3
30
1
1
12
2
2
22
2
3
32
2
Dynamic Pivot Query:-
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(Brandname) from [Table-A] FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'),1,1,'')
set #query = 'SELECT Slab,' + #cols + '
from
(
select a.BrandName, b.Rate,b.Slab from [Table-A] a inner join [Table-B] b on a.productid=b.productid
) x
pivot
(
max(Rate)
for Brandname in (' + #cols + ')
) p '
execute(#query)
Result:-
Slab
A Brand
C Brand
K Brand
1
30
10
20
2
32
12
22
But I need to order Brandname Column using productid
Expected Result:-
Slab
C Brand
K Brand
A Brand
1
10
20
30
2
12
22
32
While preparing column list for dynamic pivot use order by productid and remove distinct your problem will be solved.
Schema and insert statements:
create table [Table-A](Productid int,Brandname varchar(10));
insert into [Table-A] values(1 ,'C Brand');
insert into [Table-A] values(2 ,'K Brand');
insert into [Table-A] values(3 ,'A Brand');
create table [Table-B] (Productid int, Rate int , Slab int)
insert into [Table-B] values(1 ,10 ,1);
insert into [Table-B] values(2 ,20 ,1);
insert into [Table-B] values(3 ,30 ,1);
insert into [Table-B] values(1 ,12 ,2);
insert into [Table-B] values(2 ,22 ,2);
insert into [Table-B] values(3 ,32,2);
Query:
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT ',' + QUOTENAME(Brandname) from [Table-A] order by productid FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'),1,1,'')
set #query = 'SELECT Slab,' + #cols + '
from
(
select a.BrandName, b.Rate,b.Slab from [Table-A] a inner join [Table-B] b on a.productid=b.productid
) x
pivot
(
max(Rate)
for Brandname in (' + #cols + ')
) p '
execute(#query)
Output:
Slab
C Brand
K Brand
A Brand
1
10
20
30
2
12
22
32
If you are using SQL Server 2017 or above string_agg() will be smarter and faster option.
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select distinct #cols=STRING_AGG(quotename(brandname),',') from [Table-A]
set #query = 'SELECT Slab,' + #cols + '
from
(
select a.BrandName, b.Rate,b.Slab from [Table-A] a inner join [Table-B] b on a.productid=b.productid
) x
pivot
(
max(Rate)
for Brandname in (' + #cols + ')
) p '
execute(#query)
Output:
Slab
C Brand
K Brand
A Brand
1
10
20
30
2
12
22
32
db<>fiddle here
You want the columns to be in a particular order. You don't seem to need the SELECT DISTINCT in the subquery, based on your data. But if you do, you can use aggregation instead:
select #cols = STUFF((SELECT ',' + QUOTENAME(Brandname)
FROM [Table-A]
GROUP BY BrandName
ORDER BY MIN(ProductId)
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'
), 1, 1, '')
However, without aggregation:
select #cols = STUFF((SELECT ',' + QUOTENAME(Brandname)
FROM [Table-A]
ORDER BY ProductId
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'
), 1, 1, '');
Once #cols is in the right order, the rest of the query should fall into place.

pivot in sql server 2012 with uniqeness

if i have a table like given below.
declare #mytble table
(
orders int,
product varchar (50),
quantity int
)
INSERT #mytble
SELECT 100,'CUP','1' UNION ALL
SELECT 100, 'PLATE',2 UNION ALL
SELECT 101,'CUP','1' UNION ALL
SELECT 102,'CUP','2' UNION ALL
SELECT 103, 'CUP',1 UNION ALL
SELECT 103,'PLATE','3' UNION ALL
SELECT 103,'GLASS','1'
SELECT * FROM #mytble
will it be possible to get output like this.
any suggestion please.
With some dynamic SQL and Dense_Rank() function
Declare #SQL varchar(max)
Select #SQL = Stuff((Select Distinct ',' + QuoteName(concat('Product',Dense_Rank() over (Order By Product)))
+ ',' + QuoteName(concat('Quantity',Dense_Rank() over (Order By Product)))
From myTable For XML Path('')),1,1,'')
Select #SQL = 'Select Orders,' + #SQL + '
From (
Select Orders,Item=concat(''Product'',Dense_Rank() over (Order By Product)),Val=cast(Product as varchar(max)) From myTable
Union All
Select Orders,Item=concat(''Quantity'',Dense_Rank() over (Order By Product)),Val=cast(Quantity as varchar(max)) From myTable
) A
Pivot (max(Val) For Item in (' + #SQL + ') ) p'
Exec(#SQL);
Returns
Orders Product1 Quantity1 Product2 Quantity2 Product3 Quantity3
100 CUP 1 NULL NULL PLATE 2
101 CUP 1 NULL NULL NULL NULL
102 CUP 2 NULL NULL NULL NULL
103 CUP 1 GLASS 1 PLATE 3

Change Columns Name dynamically in sql

I have a query result like this :
Date User1 User2 User3 ....
----------------------------------
1/1/2000 55 78 98 ...
1/1/2001 26 33 56 ...
1/1/2002 88 67 12 ...
The number of columns is not known because it is the result of a pivot query.
I would like to change the name the columns to something that looks like this :
Date User1 (blue) User2 (green) User3(brown)
The color is an information I retrieve from another table.
How can I achieve this ?
Thanks
Edit : Here is the query.
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(C.Name)
from [History]
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT [Date],' + #cols +'
from
(
select [Date], Name, Value
from [History]
) x
pivot
(
max(value)
for Name in (' + #cols + ')
) p '
execute(#query)
SQL Fiddle
Schema Setup:
create table history (date datetime, name varchar(10), value int);
insert history values
('20130101', 'user1', 123),
('20130101', 'user2', 124),
('20130101', 'user3', 125),
('20130102', 'user1', 223),
('20130102', 'user3', 223),
('20130103', 'user2', 323);
create table colours (name varchar(10), colour_name varchar(10));
insert colours values
('user1', 'blue'),
('user2', 'green'),
('user3', 'brown');
Query:
DECLARE #scols nvarchar(max),
#cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX);
select #cols = STUFF((
SELECT ',' + QUOTENAME(C.Name)
from (select distinct name from [History]) C
ORDER BY C.Name
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),1,1,'');
select #scols = STUFF((
SELECT ',' + QUOTENAME(Name) + ' AS ' + QUOTENAME(colour_Name)
from (select distinct c.name, x.colour_name
from [History] C
JOIN colours x on x.name = c.name) y
ORDER BY Name
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),1,1,'');
set #query = '
SELECT [Date],' + #scols +'
from (
select [Date], Name, Value
from [History]
) x
pivot
(
max(value)
for Name in (' + #cols + ')
) p ';
-- print #query --<< uncomment this line to see the query that gets generated
exec (#query);
Results:
| DATE | BLUE | GREEN | BROWN |
-------------------------------------------------------------
| January, 01 2013 00:00:00+0000 | 123 | 124 | 125 |
| January, 02 2013 00:00:00+0000 | 223 | (null) | 223 |
| January, 03 2013 00:00:00+0000 | (null) | 323 | (null) |
To get the mapping You can use a lookup table of old column name to new column name for example
CREATE TABLE colname(
oldname varchar(20),
newname varchar(20)
)
insert into colname values ( 'user1','user1 (blue)');
insert into colname values ( 'user2','user2 (green)');
then you can build an sql statement that uses this mapping
declare #sq varchar(2000)
set #sq ='select date'
select #sq = #sq + ',' + oldname + ' as [' + newname +']' from colname
set #sq = #sq + 'from ( existing query goes here ) '
select #sq
when the sql in #sq looks good you can replace the last select with
exec ( #sq )
to run the query
select Date, User1 as blue,User2 as green,User3 as brown from tableName
Use query like this.
Make use of 'as' keyword for changing column name.