SQL Server dynamic groupby pivot - sql-server

I have the following structure in a SQL Server 2008 database. I am trying to create a script to replicate the output shown below.
It is generated by:
groupby on RPT_ID, FILE_ID, LINE_ID,
distinct columns from COLUMN_LITH and 'first' values in COLUMN_VALUES (COLUMN_NAME is dropped)
I am a beginner in SQL so this is beyond me. Any help whatsoever would be greatly appreciated.
Thanks in advance
SOURCE:
TARGET:

Using dynamic pivot, it might be an option.
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX);
SET #cols = STUFF((SELECT distinct ',' + QUOTENAME(c.column_name)
FROM your_table_name c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT RPT_ID, FILE_ID, LINE_ID' + #cols + ' from
(
select RPT_ID
, FILE_ID
, LINE_ID
, column_values
, column_name
from your_table_name
) x
pivot
(
max(column_values)
for column_name in (' + #cols + ')
) p '
execute(#query)

Related

Get the column's data in procedure? [duplicate]

I have the following data output from my database
Observation 1 aug -2015
Improvement suggestion 1 dec -2015
Observation 1 dec -2015
Accident 2 jan -2016
Non Conformity 5 jan -2016
Observation 5 jan -2016
I've tried to figure out how to use PIVOT-table to make this work but cannot make it work. The date is dynamic depending on a date in the database. The output I am looking for is like below. Can someone please point me into right direction?
Look at the fiddle what I've tried so far I know it is using SUM right now, and that is not correct, but I cannot figure out what to use. http://sqlfiddle.com/#!3/0bd0c/4
PS. The data and the image are not related, so don't be fooled by the image. It is just an example
Is this what you were looking for:
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT DISTINCT ',' + QUOTENAME(ColumnName)
from tempData
group by ColumnName, name
FOR XML PATH(''), Type
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = N'SELECT Name, ' + #cols + N' from
(
select Name, value, ColumnName
from tempData
) x
pivot
(
SUM(value)
for ColumnName in (' + #cols + N')
) p '
exec sp_executesql #query;
Changing this in your fiddle return the rows as you need it.
Try it like this:
DECLARE #cols AS NVARCHAR(MAX)=
STUFF(
(
SELECT DISTINCT ',[' + ColumnName + ']'
FROM tempData
FOR XML PATH('')
)
,1,1,'');
DECLARE #SqlCmd VARCHAR(MAX)=
'SELECT p.*
FROM
(
SELECT *
FROM tempData
) AS tbl
PIVOT
(
SUM(Value) FOR ColumnName IN(' + #cols +')
) AS p';
EXEC(#SqlCmd);

Create indexed view from defined pivot table

I have a requirement of creating a view for pivot table
This is my source table
According to my requirement I have created the following pivot table
DECLARE #cols AS NVARCHAR(MAX), #query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT ',' + QUOTENAME(Date)
from Salse_Data
group by Date
order by Date
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT Product,' + #cols + ' from
(
select Product, Date, Salse
from Salse_Data
) x
pivot
(
sum(Salse)
for Date in (' + #cols + ')
) p '
execute(#query);
Output is
I need to create an indexed view(Materialized View) above query
So i used procedure to create the view
CREATE PROCEDURE [dbo].[ProductSalse_By_Year_Proc_4]
AS
BEGIN
DECLARE #cols AS NVARCHAR(MAX), #query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT ',' + QUOTENAME(Date)
from Salse_Data
group by Date
order by Date
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'CREATE VIEW abcd with schemabinding as SELECT Product,' + #cols + ' from
(
select Product, Date, Salse
from Salse_Data
) x
pivot
(
sum(Salse)
for Date in (' + #cols + ')
) p '
EXECUTE(#query)
END
GO
this execuce without errors but not created the view.
Could you please help on this issue?

Dynamic Pivot with column names from dynamic tables

I am working on a project with SSRS and Rockwell Software's RSView32. Basically this software project logs manufacturing data to individual tables as such:
One table (Machine1_TagTable) has Tag names which describe the data as such: TagName, TagIndex. The name provides a human-understandable reference to the information contained in a second table. Example : Part Number, 1
The second table (Machine1_FloatTable) contains raw data with nothing more than a timestamp, TagIndex and value.
Example : 2013-12-10 15:44:11.322, 1, 12345(value)
I have a dynamic pivot which works for ONE table; however, I would like to use a variable parameter passed from SSRS to select both the TagTable and FloatTable.
This works with the Machine1_FloatTable as part of the dynamic statement, but not in the XML path building. I understand this is a scope issue, so I'm looking for creative ways to allow me to pass the table names from SSRS into this stored procedure.
Here's what I have now:
DECLARE #FLOATTABLE NVARCHAR(MAX), #TAGTABLE NVARCHAR(MAX), #startdate NVARCHAR(MAX),
#enddate NVARCHAR(MAX), #cols as NVARCHAR(MAX), #query as NVARCHAR(MAX)
SET #TAGTABLE ='dbo.Machine1_TagTable'
SET #FLOATTABLE = 'dbo.Machine1_FloatTable'
SELECT #cols = STUFF((SELECT DISTINCT ',' + QUOTENAME(CONVERT(VARCHAR,TagName),'"')
FROM #tagtable
FOR XML PATH('')),1,1,'')
Set #query = 'SELECT DISTINCT DateAndTime, Millitm, ' + #cols + ' FROM ( select
T.DateAndTime, T.Millitm, N.TagName, T.Val from ' + #FLOATTABLE + ' T LEFT JOIN ' +
#TAGTABLE + ' N ON T.TagIndex=N.TagIndex WHERE T.DateAndTime Between '''+ #startdate +
''' AND '''+ #enddate +''') x PIVOT (MAX(Val) for TagName IN (' + #cols + ')) p'
PRINT (#query)
Any help or suggestions would be greatly appreciated. Thanks!
Well, it's possible, if I understand your question. You have to build a dynamic SQL string, and execute that to populate #cols.
declare #string nvarchar(MAX)
set #String = 'SELECT STUFF((SELECT DISTINCT '','' + QUOTENAME(CONVERT(VARCHAR,ActualDate),'
+ '''"'') FROM ' + #TAGTABLE + ' FOR XML PATH ('''')),1,1,'''')'
EXECUTE sp_executeSQL #String, #Cols OUTPUT
print #cols
It's pretty hacky, but I think it should work.

Generate dynamic columns using pivot

I have the following query which is always giving the error. Could some body help me
to resolve this?
"Incorrect syntax near the keyword '#stqsql'".
My code is:
declare #strsql nvarchar(max)
set #strsql=select merchantid from employee
select *
from
(
Select s.employeeid,
COUNT(*) as TotCount
from Employee s
GROUP BY s.employeeid
)as a
pivot (avg(TotCount) for employeeid IN ('+#stqsql+')) AS NoOfRec
Unfortunately the way you are trying to get dynamic columns does not work. You will have to use something similar to the following:
DECLARE #colsPivot AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
-- this gets the list of values that you want to pivot
select #colsPivot = STUFF((SELECT distinct ', ' + QUOTENAME(merchantid )
from employee
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
-- since you are use a dynamic list you have to use dynamic sql
set #query = 'SELECT ' + #colsPivot + ' from
(
SELECT s.employeeid,
COUNT(*) as TotCount
FROM Employee s
GROUP BY s.employeeid
) src
pivot
(
avg(TotCount)
for employeeid in (' + #colsPivot + ')
) p '
execute(#query)

TSQL Pivot Long List of Columns

I am looking to use pivot function to convert row values of a column into separate columns. There are 100+ distinct values in that column and hard-coding each and every single value in the 'for' clause of the pivot function would be very time consuming and not good from maintainability purposes. I was wondering if there is any easier way to tackle this problem?
Thanks
You can use Dynamic SQL in a PIVOT for this type of query. Dynamic SQL will get the list of the items that you want to transform on execution which prevents the need to hard-code each item:
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
SET #cols = STUFF((SELECT distinct ',' + QUOTENAME(c.condition_id)
FROM t c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT memid, ' + #cols + ' from
(
select MemId, Condition_id, condition_result
from t
) x
pivot
(
sum(condition_result)
for condition_id in (' + #cols + ')
) p '
execute(#query)
See SQL Fiddle with Demo
If you post a sample of data that you need to transform, then I can adjust my query to demonstrate.
I was trying to do this and had db2 Data like this.
id,MCD1,MCD2,MCD3,MCD4
1,4,5,4,3
2,6,7,8,9
3,3,6,2,6
4,2,5,8,4
5,3,4,5,6
I wrote this Dynamic SQL in TSQL
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
SET #cols = STUFF((SELECT ',', COLUMN_NAME FROM my_db.INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME LIKE 'PivotLonger' AND COLUMN_NAME like 'MCD%'
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT id, MCD, Value
from [my_db].[dbo].[PivotLonger]
UNPIVOT
(Value FOR MCD IN (' + #cols + ')) AS unpvt'
execute(#query)
Resulted in expanding the columns into a nice long table :)
id,MCD,Value
1,MCD1,4
1,MCD2,5
1,MCD3,4
1,MCD4,3
2,MCD1,6
2,MCD2,7
2,MCD3,8
2,MCD4,9
3,MCD1,3
3,MCD2,6
3,MCD3,2
3,MCD4,6
4,MCD1,2
4,MCD2,5
4,MCD3,8
4,MCD4,4
5,MCD1,3
5,MCD2,4
5,MCD3,5
5,MCD4,6

Resources