dbaSQL
asked on
PIVOT SQL 2008
v2008, I've used this transform a million times successfully for cross-tab/pivot resultsets:
http://www.itrain.de/knowhow/sql/tsql/pivot/pivotsample.asp
it isn't working now, and i just am seriously tired of trying to fix it. my failure is this:
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near ','.
Msg 319, Level 15, State 1, Line 1
Incorrect syntax near the keyword 'with'. If this statement is a common table expression, an xmlnamespaces clause or a change tracking context clause, the previous statement must be terminated with a semicolon.
I've read and read many references out there as to the cause of this, but it's not a CTE per se and again, i'm just seriously tired of working this one, i would like to use the new PIVOT in v2008.
every reference I've seen on PIVOT, however, suggests that I have to hard-code an IN list. surely I am misinterpretting this. for example:
USE AdventureWorks;
GO
SELECT VendorID, [164] AS Emp1, [198] AS Emp2, [223] AS Emp3, [231] AS Emp4, [233] AS Emp5
FROM
(SELECT PurchaseOrderID, EmployeeID, VendorID
FROM Purchasing.PurchaseOrderHe ader) p
PIVOT
( COUNT (PurchaseOrderID)
FOR EmployeeID IN ( [164], [198], [223], [231], [233] ) <<<<<<<<<< THIS IN LIST
) AS pvt
ORDER BY pvt.VendorID;
i just want that code below to return this:
symbol1, symbol2, symbol3...........
date1 12 157 15
date2 100 6000 3599
date3 538 752 7
.........
....
Do I have to do the PIVOT with dynamic sql?
http://www.itrain.de/knowhow/sql/tsql/pivot/pivotsample.asp
it isn't working now, and i just am seriously tired of trying to fix it. my failure is this:
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near ','.
Msg 319, Level 15, State 1, Line 1
Incorrect syntax near the keyword 'with'. If this statement is a common table expression, an xmlnamespaces clause or a change tracking context clause, the previous statement must be terminated with a semicolon.
I've read and read many references out there as to the cause of this, but it's not a CTE per se and again, i'm just seriously tired of working this one, i would like to use the new PIVOT in v2008.
every reference I've seen on PIVOT, however, suggests that I have to hard-code an IN list. surely I am misinterpretting this. for example:
USE AdventureWorks;
GO
SELECT VendorID, [164] AS Emp1, [198] AS Emp2, [223] AS Emp3, [231] AS Emp4, [233] AS Emp5
FROM
(SELECT PurchaseOrderID, EmployeeID, VendorID
FROM Purchasing.PurchaseOrderHe
PIVOT
( COUNT (PurchaseOrderID)
FOR EmployeeID IN ( [164], [198], [223], [231], [233] ) <<<<<<<<<< THIS IN LIST
) AS pvt
ORDER BY pvt.VendorID;
i just want that code below to return this:
symbol1, symbol2, symbol3...........
date1 12 157 15
date2 100 6000 3599
date3 538 752 7
.........
....
Do I have to do the PIVOT with dynamic sql?
SELECT Symbol,
CONVERT(VARCHAR(10),DateField,101) AS [Date],
SUM(quantity) AS Volume
FROM tablename
WHERE field='XYZ'
AND (symbol LIKE 'xx%' OR symbol LIKE 'yy%' OR symbol LIKE 'zz%' OR symbol LIKE 'JJ%' or symbol IN ('aa','bb','cc')
OR Symbol LIKE 'klm__')
GROUP BY Symbol,CONVERT(VARCHAR(10),DateField,101)
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
wow. not there yet, but very first go is pretty darned good. back soon
ASKER
just want to play with the NULLs that you get if/when a value is not there on a given day. back soon...
If it is a finite list, you can always explicitly list out the column list and then just wrap the column with COALESCE or ISNULL, but see how your tests go. Definitely how it functions though if the column that ends up as your row identifier doesn't match to all the pivoted columns.
ASKER
so. i create a test table. tstVOLUME -- ID, Symbol, Date, Volume
within which i insert that code up there:
SELECT Symbol,
CONVERT(VARCHAR(10),DateFi eld,101) AS [Date],
SUM(quantity) AS Volume
FROM tablename
WHERE field='XYZ'
AND (symbol LIKE 'xx%' OR symbol LIKE 'yy%' OR symbol LIKE 'zz%' OR symbol LIKE 'JJ%' or symbol IN ('aa','bb','cc')
OR Symbol LIKE 'klm__')
GROUP BY Symbol,CONVERT(VARCHAR(10) ,DateField ,101)
the source table is 6 months of data, 85,433,421 records. as you can see, I use no time parms.
the insertion itself takes exactly :01 second. It writes 2333 rows.
i then run the code snippet below. it, too, completes instantly. (less than a second), and returns exactly the data i am looking for.
i need to wrap that code snippet into a procedure. no biggie.
and I want to return '0' instead of 'NULL' if/when a symbol wasn't traded on a particular day.
i also need to dump it to csv, so i may do something in SSIS, but but other than that, this is pretty damn good. lightening fast. excellent.
Kevin, very big thank you.
Mark, thanks to you as well. Very clever solution.
within which i insert that code up there:
SELECT Symbol,
CONVERT(VARCHAR(10),DateFi
SUM(quantity) AS Volume
FROM tablename
WHERE field='XYZ'
AND (symbol LIKE 'xx%' OR symbol LIKE 'yy%' OR symbol LIKE 'zz%' OR symbol LIKE 'JJ%' or symbol IN ('aa','bb','cc')
OR Symbol LIKE 'klm__')
GROUP BY Symbol,CONVERT(VARCHAR(10)
the source table is 6 months of data, 85,433,421 records. as you can see, I use no time parms.
the insertion itself takes exactly :01 second. It writes 2333 rows.
i then run the code snippet below. it, too, completes instantly. (less than a second), and returns exactly the data i am looking for.
i need to wrap that code snippet into a procedure. no biggie.
and I want to return '0' instead of 'NULL' if/when a symbol wasn't traded on a particular day.
i also need to dump it to csv, so i may do something in SSIS, but but other than that, this is pretty damn good. lightening fast. excellent.
Kevin, very big thank you.
Mark, thanks to you as well. Very clever solution.
DECLARE
@sourcedata varchar(8000),
@Pivot_On_Source_Column varchar(2000),
@Pivot_Value_Aggregate varchar(10),
@Pivot_Value_Column varchar(2000),
@Pivot_Column_List varchar(2000),
@Pivot_Column_Style_Code varchar(4) -- used in convert for style code
set @sourcedata = 'tstVOLUME'
set @pivot_on_source_column = 'Date'
set @pivot_value_aggregate = 'sum'
set @pivot_value_column = 'Volume'
set @pivot_column_list = 'Symbol'
set @pivot_column_style_code = ',106'
-- we really should put in some error checking, e.g. if anything is NULL it will crash.
declare @columns varchar(max)
declare @sql nvarchar(max)
set @sql = N'set @columns = substring((select '', [''+convert(varchar,'+@Pivot_Column_List+@Pivot_Column_Style_Code+')+'']'' from '+@sourcedata+' group by '+@Pivot_Column_List+' for xml path('''')),2,8000)'
execute sp_executesql @sql,
N'@columns varchar(max) output',
@columns=@columns output
set @sql = N'SELECT * FROM
(SELECT '+@Pivot_On_Source_Column+','+@Pivot_Column_List+','+@Pivot_Value_Column+' from '+@sourcedata+') src
PIVOT
('+@Pivot_Value_Aggregate+'('+@Pivot_Value_Column+') FOR '+@Pivot_Column_List+' IN ('+@columns+') ) pvt
ORDER BY '+@pivot_on_source_column+''
execute sp_executesql @sql
ASKER
Excellent.
You are most welcome, dbaSQL.
Happy coding!
Best regards,
Kevin
P.S. since you did find it helpful, please don't forget to vote on Mark's article. ;)
Happy coding!
Best regards,
Kevin
P.S. since you did find it helpful, please don't forget to vote on Mark's article. ;)
ASKER
Yep. Already have. Thanks again, Kevin.
ASKER
just a quicky... i'm trying to ISNULL my @pivot_column_list
original:
set @sql = N'set @columns = substring((select '', [''+convert(varchar,'+@Piv ot_Column_ List+@Pivo t_Column_S tyle_Code+ ')+'']'' from '+@sourcedata+' group by '+@Pivot_Column_List+' for xml path('''')),2,8000)'
attempt:
set @sql = N'set @columns = substring((select '', [''+convert(varchar,(ISNUL L('+@Pivot _Column_Li st+',0)'+@ Pivot_Colu mn_Style_C ode+')+''] '' from '+@sourcedata+' group by '+@Pivot_Column_List+' for xml path('''')),2,8000)'
output:
Server: Msg 102, Level 15, State 1, Line 1
Incorrect syntax near ','.
original:
set @sql = N'set @columns = substring((select '', [''+convert(varchar,'+@Piv
attempt:
set @sql = N'set @columns = substring((select '', [''+convert(varchar,(ISNUL
output:
Server: Msg 102, Level 15, State 1, Line 1
Incorrect syntax near ','.
you have an extra ( in your line right before the ISNULL:
set @sql = N'set @columns = substring((select '', [''+convert(varchar,ISNULL ('+@Pivot_ Column_Lis t+',0)'+@P ivot_Colum n_Style_Co de+')+'']' ' from '+@sourcedata+' group by '+@Pivot_Column_List+' for xml path('''')),2,8000)'
set @sql = N'set @columns = substring((select '', [''+convert(varchar,ISNULL
Don't think that is the correct placement for that adjustment. You would need the ISNULL within the select list which you see is "SELECT * FROM ...". You would have to specify the hard coded value (e.g. Symbol2) there like this "SELECT ISNULL(Symbol2, 0) FROM ...".
ASKER
that's not going to work. (don't want to hard code) they symbols are dynamic
it's fine, though
thank you again, kevin
it's fine, though
thank you again, kevin
ASKER
last one, i promise.
can this be done on v2000? i've put a proc together in v2008, it all works perfectly.
but, i have to run it on my historical data.... which is still sitting in v2000
max and for xml path maybe not. curious if you had any ideas
can this be done on v2000? i've put a proc together in v2008, it all works perfectly.
but, i have to run it on my historical data.... which is still sitting in v2000
max and for xml path maybe not. curious if you had any ideas
PIVOT keyword is not available in SQL Server 2000, sorry.
One thought would be to create a linked server to your SQL Server 2000 instance and then on your SQL Server 2005 instance try to create a view from data using four part naming:
CREATE VIEW vw_HistoricalData
AS
SELECT * FROM linkedserver.database.dbo. tablename;
Then try to use this view in your stored procedure to PIVOT.
Not sure that will work, but in theory it should.
CREATE VIEW vw_HistoricalData
AS
SELECT * FROM linkedserver.database.dbo.
Then try to use this view in your stored procedure to PIVOT.
Not sure that will work, but in theory it should.
ASKER