Calculation in SQL Server 2012 - sql

This is my code which is not working properly. I need only one record inserted for an employee but it inserts multiple
CREATE TABLE #Table1 (ID VARCHAR(5), formula VARCHAR(MAX))
CREATE TABLE #table2 (employeid VARCHAR(5), payhead VARCHAR(5), amount MONEY)
CREATE TABLE #table3 (employeid VARCHAR(5), payiD VARCHAR(5), amount MONEY)
INSERT INTO #Table1
VALUES ('PAY1', NULL), ('PAY2', '(PAY1*12%)'), ('PAY3', 'PAY1 + PAY2')
INSERT INTO #Table2
VALUES ('E001','PAY1', 2000),('E002','PAY1', 5000),('E003','PAY1', 3000)
INSERT INTO #Table2
VALUES ('E001','PAY3', 1000),('E002','PAY3', 3000),('E003','PAY3', 2000)
DECLARE #SQL VARCHAR (MAX) = ''
SELECT #SQL = #SQL + '
CROSS APPLY (
SELECT ' + ID + ' = ' + REPLACE(formula,'%','/100') + '
)
AS ' + ID + '
'
FROM #Table1
WHERE formula IS NOT NULL
SET #SQL = ';WITH cte AS
(
SELECT employeid, Amount as Pay1
FROM #table2
WHERE EMPLOYEID = ''E001''
)
SELECT *
INTO #TMP -- insert the result into a new temp table
FROM
cte ' + #SQL + '
INSERT #Table3
SELECT EmployeID, PayID, Amount
FROM #TMP
CROSS APPLY (
VALUES ' + STUFF(
(SELECT ',' + '(''' + ID + ''',' + ID + ')' FROM
#Table1 FOR XML PATH ('')), 1, 1, ''
) + '
) A(PayID, Amount)
SELECT * FROM #TMP
DROP TABLE #TMP'
PRINT(#SQL)
EXEC(#SQL)
SELECT * FROM #table3 WHERE employeid='E001'
DROP TABLE #table1
DROP TABLE #table2
DROP TABLE #table3
my problem is there are 2 employee E001, E002, and three pay code.so after executing it should show one record as one employee.but it shows multiple.secondly, if add pay3 like below
('PAY2', '(PAY1+PAY3*12%)') Then it not working.

Related

How to create a table with pivot results using SELECT * INTO ( PIVOT Result query) [duplicate]

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.

How to provide custom name to column in pivoting

I have a table like this:
id unit
1 mm
2 cm
3 kg
When I perform pivot operation on this, I am getting result as follows:
1 2 3
mm cm kg
Is it possible to get custom column names here, something like this:
d1 d2 d3
mm cm kg
I am using Pivot for this as:
IF OBJECT_ID('tempdb..#t') IS NOT NULL
DROP TABLE #t
GO
CREATE table #t
(id varchar(max),unit varchar(max))
insert into #t (id,unit)values
(1,'kg'),
(2,'cm'),
(3,'mm'),
(4,'m')
DECLARE #statement NVARCHAR(max)
,#columns NVARCHAR(max)
SELECT #columns = ISNULL(#columns + ',', '') + N'[' + cast(tbl.id as varchar(max)) + ']'
FROM (
SELECT DISTINCT id
FROM #t
) AS tbl
SELECT #statement = 'select *
INTO ##temp
from (
SELECT id,[unit]
FROM #t
) as s
PIVOT
(max(unit) FOR id in(' + #columns + ')) as pvt
'
EXEC sp_executesql #statement = #statement
SELECT * FROM ##temp
DROP TABLE #t
DROP TABLE ##temp
Is it possible?
Thanks
IF OBJECT_ID('tempdb..#t') IS NOT NULL
DROP TABLE #t
GO
CREATE TABLE #t (
id VARCHAR(10),
unit VARCHAR(100)
)
INSERT INTO #t (id, unit)
VALUES
('1', 'kg'),
('2', 'cm'),
('3', 'mm'),
('4', 'mm')
DECLARE #SQL NVARCHAR(MAX), #columns NVARCHAR(MAX)
SELECT #columns = STUFF((
SELECT ',[D' + id + ']'
FROM #t
FOR XML PATH('')), 1, 1, '')
SELECT #SQL = '
SELECT *
FROM (
SELECT [unit], col = N''D'' + id
FROM #t
) s
PIVOT (MAX(unit) FOR col IN (' + #columns + ')) p'
EXEC sys.sp_executesql #SQL
Just add a prefix to your ID. Example
SELECT #statement = 'select * INTO ##temp from
( SELECT [id] = ''d''+id,[unit] FROM #t ) as s
PIVOT
(max(unit) FOR id in(' + #columns + ')) as pvt '
Also it's terrible practice to use global temp tables! Especially one named ##temp
You can use a CASE expression with a dynamic sql query.
CREATE TABLE #t
(
id INT,
unit VARCHAR(2)
);
INSERT INTO #t VALUES
(1,'mm'),
(2,'cm'),
(3,'kg');
DECLARE #query AS VARCHAR(MAX);
SELECT #query = 'SELECT ' +
STUFF
(
(
SELECT DISTINCT ',MAX(CASE WHEN id = '+ CAST(id AS VARCHAR(10))
+ ' THEN unit END) AS d' + CAST(id AS VARCHAR(10))
FROM #t
FOR XML PATH('')
),
1,1,'');
SELECT #query += ' FROM #t;';
EXECUTE(#query);
Result
+----+----+----+
| d1 | d2 | d3 |
+----+----+----+
| mm | cm | kg |
+----+----+----+
SELECT #statement = 'select * INTO ##temp from ( SELECT ''d''+id AS [id],[unit] FROM #t ) as s PIVOT (max(unit) FOR id in(' + #columns + ')) as pvt '

SQL Server 2005 - Dynamic PIVOT query

I require your kind help on a PIVOT query problem.
The scenario is I have a voting system. Comprises of 3 tables.
Elections, Candidates, Votes.
The PIVOT relates to PIVOTing the Candidate names as Columns and having the VOTE data as the data.
So far I have attemped this and not got it to work, I've gotten into a muddle with it :(
CREATE TABLE #MYELECTIONS (E_POSITION_CODE INT, E_POSITIONNAME VARCHAR(50))
INSERT INTO #MYELECTIONS VALUES (147,'MANAGER')
INSERT INTO #MYELECTIONS VALUES (148,'CHEF')
INSERT INTO #MYELECTIONS VALUES (149,'WAITER')
CREATE TABLE #MYCANDIDATES (C_CANDIDATE_CODE INT,
C_CANDIDATENAME VARCHAR (50), C_POSITION_CODE INT)
INSERT INTO #MYCANDIDATES VALUES (100,'TOM CRUISE', 147)
INSERT INTO #MYCANDIDATES VALUES (101,'MICKY MOUSE', 147)
INSERT INTO #MYCANDIDATES VALUES (103,'DONALD DUCK', 147)
INSERT INTO #MYCANDIDATES VALUES (100,'TOM CRUISE', 148)
CREATE TABLE #MYVOTES (V_POSITION_CODE INT,
V_CANDIDATE_CODE INT, VOTINGPREFERENCE SMALLINT)
INSERT INTO #MYVOTES VALUES (147,100,1)
INSERT INTO #MYVOTES VALUES (147,100,1)
INSERT INTO #MYVOTES VALUES (147,100,1)
INSERT INTO #MYVOTES VALUES (147,100,1)
INSERT INTO #MYVOTES VALUES (147,101,1)
INSERT INTO #MYVOTES VALUES (147,101,1)
INSERT INTO #MYVOTES VALUES (147,103,1)
INSERT INTO #MYVOTES VALUES (148,100,1)
INSERT INTO #MYVOTES VALUES (148,100,1)
DECLARE #DynamicPivotQuery AS NVARCHAR(MAX)
DECLARE #ColumnName AS NVARCHAR(MAX)
DECLARE #MyPositionCode AS INT
SET #MyPositionCode = 147
DECLARE #MyOutput AS NVARCHAR(MAX)
--Get distinct values of the PIVOT Column
SELECT #ColumnName = ISNULL(#ColumnName + ',','')
+ QUOTENAME(C_CANDIDATENAME)
FROM (SELECT TOP 100 PERCENT C_CANDIDATENAME
FROM #MYCANDIDATES
WHERE C_POSITION_CODE = #MyPositionCode
ORDER BY C_CANDIDATE_CODE) AS C_CANDIDATENAME
--Prepare the `PIVOT` query using the dynamic sql
SET #DynamicPivotQuery =
N'SELECT ROW_NUMBER() OVER (ORDER BY E_POSITIONNAME) AS Idnum,
E_POSITIONNAME AS [Position Name], ' + #ColumnName + '
FROM #MYVOTES
INNER JOIN #MYELECTIONS
ON (#MYVOTES.V_POSITION_CODE = #MYELECTIONS.E_POSITION_CODE)
PIVOT(SUM(VOTINGPREFERENCE))
FOR C_CANDIDATENAME IN (' + #ColumnName + ') AS PVTTable
WHERE #MYELECTIONS.E_POSITION_CODE = 147'
--Execute the Dynamic Pivot Query
EXEC sp_executesql #DynamicPivotQuery,
#MyOutput = #MyOutput OUTPUT
SELECT #MyOutput
DROP TABLE #MYELECTIONS
DROP TABLE #MYCANDIDATES
DROP TABLE #MYVOTES
It has to be a dynamic PIVOT as the Candidate Names that I want to Pivot as Columns, could be dynamic depending on how many Candidates there are for an Election position.
The desired output for the above would be like this:-
Election #MyPositionCode = 147
Idnum Position_Name TOM CRUISE MICKY MOUSE DONALD DUCK...
1 MANAGER 4 2 1
Election #MyPositionCode = 148
Idnum Position_Name TOM CRUISE MICKY MOUSE DONALD DUCK...
1 CHEF 2 0 0
Try this
DECLARE #MyPositionCode AS INT
SET #MyPositionCode = 147
Declare the variables for selecting dynamic columns
DECLARE #DynamicPivotQuery AS NVARCHAR(MAX)
DECLARE #ColumnName AS NVARCHAR(MAX)
DECLARE #cols NVARCHAR (MAX)
SELECT #cols = COALESCE (#cols + ',[' + C_CANDIDATENAME + ']', '[' + C_CANDIDATENAME + ']')
FROM
(
SELECT TOP 100 PERCENT C_CANDIDATENAME
FROM #MYCANDIDATES
WHERE C_POSITION_CODE = #MyPositionCode
ORDER BY C_CANDIDATE_CODE
) PV
ORDER BY C_CANDIDATENAME desc
If you want to replace NULL with zero
DECLARE #NulltoZeroCols NVARCHAR (MAX)
SELECT #NullToZeroCols = SUBSTRING((SELECT ',ISNULL(['+C_CANDIDATENAME+'],0) AS ['+C_CANDIDATENAME+']'
FROM
(
SELECT TOP 100 PERCENT C_CANDIDATENAME
FROM #MYCANDIDATES
WHERE C_POSITION_CODE = #MyPositionCode
ORDER BY C_CANDIDATE_CODE
)TAB
ORDER BY C_CANDIDATENAME desc FOR XML PATH('')),2,8000)
Now pivot it dynamically. I have written the logic inside
DECLARE #query NVARCHAR(MAX)
SET #query = '-- You can apply ROW_NUMBER() here which is the data after pivot
SELECT ROW_NUMBER() OVER (ORDER BY E_POSITIONNAME) AS Idnum,
,E_POSITIONNAME,'+#NullToZeroCols+'
FROM
(
-- Select data before pivot
SELECT TOP 100 PERCENT ME.E_POSITIONNAME,MC.C_CANDIDATENAME,
COUNT(MC.C_CANDIDATENAME) OVER(PARTITION BY ME.E_POSITIONNAME,MC.C_CANDIDATENAME) CNT
FROM #MYELECTIONS ME
JOIN #MYCANDIDATES MC ON ME.E_POSITION_CODE=MC.C_POSITION_CODE
JOIN #MYVOTES MV ON MC.C_CANDIDATE_CODE=MV.V_CANDIDATE_CODE
AND MV.V_POSITION_CODE=MC.C_POSITION_CODE
WHERE MC.C_POSITION_CODE = ' + CAST(#MyPositionCode AS VARCHAR(30)) + '
) x
PIVOT
(
MIN(CNT)
FOR C_CANDIDATENAME IN (' + #cols + ')
) p
;'
EXEC SP_EXECUTESQL #query
Click the below link. If the result is not auto-generated, press RUN QUERY button.
Click here to view result

Way to put pivote sql result into temptable

work on sql server .Write one pivotal sql ,bellow is my tables and pivotal sql syntax.MY problem is failed to put this pivotal value in Temp table .
-----------------Table-1-------------
CREATE TABLE Table1 (ColId INT,ColName VARCHAR(10))
INSERT INTO Table1 VALUES(1, 'Country')
INSERT INTO Table1 VALUES(2, 'MONTH')
INSERT INTO Table1 VALUES(3, 'Day')
----------------Table-2----------------------------
CREATE TABLE Table2 (tID INT,ColID INT,Txt VARCHAR(10))
INSERT INTO Table2 VALUES (1,1, 'US')
INSERT INTO Table2 VALUES (1,2, 'July')
INSERT INTO Table2 VALUES (1,3, '4')
INSERT INTO Table2 VALUES (2,1, 'US')
INSERT INTO Table2 VALUES (2,2, 'Sep')
INSERT INTO Table2 VALUES (2,3, '11')
INSERT INTO Table2 VALUES (3,1, 'US')
INSERT INTO Table2 VALUES (3,2, 'Dec')
INSERT INTO Table2 VALUES (3,3, '25')
--------------
----------------Pivotal sql----------------------------
DECLARE #query NVARCHAR(4000)
DECLARE #cols NVARCHAR(2000)
SELECT #cols = STUFF(( SELECT DISTINCT TOP 100 PERCENT
'],[' + t2.ColName
FROM Table1 AS t2
ORDER BY '],[' + t2.ColName
FOR XML PATH('')
), 1, 2, '') + ']'
SET #query = N'SELECT tID, '+
#cols +'
FROM
(SELECT t2.tID
, t1.ColName
, t2.Txt
FROM Table1 AS t1
JOIN Table2 AS t2 ON t1.ColId = t2.ColID) p
PIVOT
(
MAX([Txt])
FOR ColName IN
( '+
#cols +' )
) AS pvt
ORDER BY tID;'
EXECUTE(#query)
After execute bellow command want to use this value for rest of work ,so I need to put this command result value in temp table
EXECUTE(#query)
If you are able to do the rest of your procedure by working with EXECUTE(#Querys) you coud do something like that
Declare #TabName Varchar(40)
Select #TabName='##'+Replace(CAST(NEWID() as Varchar(40)),'-','')
DECLARE #query NVARCHAR(4000)
DECLARE #cols NVARCHAR(2000)
SELECT #cols = STUFF(( SELECT DISTINCT TOP 100 PERCENT
'],[' + t2.ColName
FROM Table1 AS t2
ORDER BY '],[' + t2.ColName
FOR XML PATH('')
), 1, 2, '') + ']'
SET #query = N'SELECT tID, '+
#cols +' into ' +#TabName + '
FROM
(SELECT t2.tID
, t1.ColName
, t2.Txt
FROM Table1 AS t1
JOIN Table2 AS t2 ON t1.ColId = t2.ColID) p
PIVOT
(
MAX([Txt])
FOR ColName IN
( '+
#cols +' )
) AS pvt
ORDER BY tID;'
Print #Query
EXECUTE(#query)
Select #query = 'Select * from ' + #Tabname
EXECUTE(#query)
Select #query = 'Drop Table ' + #Tabname
EXECUTE(#query)
If you dont want to do that, you could use a "hard" ##temptable, but you would not be able using this save withing a multiuser environment.
Try this :
Declare #Sample table
(
tID int,
Country VARCHAR(10),
Day int ,
MONTH VARCHAR(10)
)
Insert into #Sample
EXECUTE(#query)
select * from #Sample
In the same way you can create a temp table instead of table variable and insert it into it

Getting a Dynamically-Generated Pivot-Table into a Temp Table

I've seen this, so I know how to create a pivot table with a dynamically generated set of fields. My problem now is that I'd like to get the results into a temporary table.
I know that in order to get the result set into a temp table from an EXEC statement you need to predefine the temp table. In the case of a dynamically generated pivot table, there is no way to know the fields beforehand.
The only way I can think of to get this type of functionality is to create a permanent table using dynamic SQL. Is there a better way?
Ran in to this issue today, and posted on my blog. Short description of solution, is to create a temporary table with one column, and then ALTER it dynamically using sp_executesql. Then you can insert the results of the dynamic PIVOT into it. Working example below.
CREATE TABLE #Manufacturers
(
ManufacturerID INT PRIMARY KEY,
Name VARCHAR(128)
)
INSERT INTO #Manufacturers (ManufacturerID, Name)
VALUES (1,'Dell')
INSERT INTO #Manufacturers (ManufacturerID, Name)
VALUES (2,'Lenovo')
INSERT INTO #Manufacturers (ManufacturerID, Name)
VALUES (3,'HP')
CREATE TABLE #Years
(YearID INT, Description VARCHAR(128))
GO
INSERT INTO #Years (YearID, Description) VALUES (1, '2014')
INSERT INTO #Years (YearID, Description) VALUES (2, '2015')
GO
CREATE TABLE #Sales
(ManufacturerID INT, YearID INT,Revenue MONEY)
GO
INSERT INTO #Sales (ManufacturerID, YearID, Revenue) VALUES(1,2,59000000000)
INSERT INTO #Sales (ManufacturerID, YearID, Revenue) VALUES(2,2,46000000000)
INSERT INTO #Sales (ManufacturerID, YearID, Revenue) VALUES(3,2,111500000000)
INSERT INTO #Sales (ManufacturerID, YearID, Revenue) VALUES(1,1,55000000000)
INSERT INTO #Sales (ManufacturerID, YearID, Revenue) VALUES(2,1,42000000000)
INSERT INTO #Sales (ManufacturerID, YearID, Revenue) VALUES(3,1,101500000000)
GO
DECLARE #SQL AS NVARCHAR(MAX)
DECLARE #PivotColumnName AS NVARCHAR(MAX)
DECLARE #TempTableColumnName AS NVARCHAR(MAX)
DECLARE #AlterTempTable AS NVARCHAR(MAX)
--get delimited column names for various SQL statements below
SELECT
-- column names for pivot
#PivotColumnName= ISNULL(#PivotColumnName + N',',N'') + QUOTENAME(CONVERT(NVARCHAR(10),YearID)),
-- column names for insert into temp table
#TempTableColumnName = ISNULL(#TempTableColumnName + N',',N'') + QUOTENAME('Y' + CONVERT(NVARCHAR(10),YearID)),
-- column names for alteration of temp table
#AlterTempTable = ISNULL(#AlterTempTable + N',',N'') + QUOTENAME('Y' + CONVERT(NVARCHAR(10),YearID)) + ' MONEY'
FROM (SELECT DISTINCT [YearID] FROM #Sales) AS Sales
CREATE TABLE #Pivot
(
ManufacturerID INT
)
-- Thats it! Because the following step will flesh it out.
SET #SQL = 'ALTER TABLE #Pivot ADD ' + #AlterTempTable
EXEC sp_executesql #SQL
--execute the dynamic PIVOT query into the temp table
SET #SQL = N'
INSERT INTO #Pivot (ManufacturerID, ' + #TempTableColumnName + ')
SELECT ManufacturerID, ' + #PivotColumnName + '
FROM #Sales S
PIVOT(SUM(Revenue)
FOR S.YearID IN (' + #PivotColumnName + ')) AS PivotTable'
EXEC sp_executesql #SQL
SELECT M.Name, P.*
FROM #Manufacturers M
INNER JOIN #Pivot P ON M.ManufacturerID = P.ManufacturerID
you could do this:
-- add 'loopback' linkedserver
if exists (select * from master..sysservers where srvname = 'loopback')
exec sp_dropserver 'loopback'
go
exec sp_addlinkedserver #server = N'loopback',
#srvproduct = N'',
#provider = N'SQLOLEDB',
#datasrc = ##servername
go
declare #myDynamicSQL varchar(max)
select #myDynamicSQL = 'exec sp_who'
exec('
select * into #t from openquery(loopback, ''' + #myDynamicSQL + ''');
select * from #t
')
EDIT: addded dynamic sql to accept params to openquery
Let me try this explanation of select into instead. I'm running SQL Server 2005 as well. Because you have PIVOT tables I'm going to assume the same or 2008.
select
o.*,
OtherField1,
OtherField2
INTO #temp
FROM
OriginalOtherData as ood
PIVOT (
MAX([Value])
FOR Field in (OtherField1, OtherField2)
) as piv
RIGHT OUTER join
Original o on o.OriginalSD = piv.OriginalSD
select * from #temp
Drop table #temp
The only difference between a normal select and a select into is that INTO #table part.
for query (select col1, col2, col3 from tablename
col1 becomes rowlabels
col2 becomes columnheaders
col3 is the dataset
also gets rid of the global table
if OBJECT_ID('tempdb..#3') is not null drop table #3
if OBJECT_ID('tempdb..##3') is not null drop table ##3
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT distinct ',' + QUOTENAME( col2 ) from tablename FOR XML PATH(''), col2).value('.', 'NVARCHAR(MAX)'),1,1,'')
set #query = 'SELECT col1, ' + #cols + ' into ##3 from ( select col1, col2, col3 from tablename ) x pivot ( max(col3)for col2 in (' + #cols + ')) p '
execute(#query)
select * into #3 from ##3 if OBJECT_ID('tempdb..##3') -- is not null drop table ##3