Pivot dates as rows - sql

I have something like this:
From this query
SELECT DISTINCT Securitization, SUM(RemittableCollections) [RemittableCollections], ReportingDate
FROM Securitization.dbo.SecuritizationReporting
GROUP BY Securitization,ReportingDate
What I want is the Reporting dates to be on the rows, so I will have securitzation as the columns and then for each reporting date I will have a sum of Remittable collections, how can I do this?
This is what I am trying to do but it doesnt work
SELECT DISTINCT Securitization, ReportingDate
FROM Securitization.dbo.SecuritizationReporting
PIVOT
(
SUM(RemittableCollections)
for dates in (SELECT DISTINCT ReportingDate FROM Securitization.dbo.SecuritizationReporting )
)
GROUP BY Securitization,ReportingDate

Untested, but perhaps this will help
Declare #SQL varchar(max) = '
Select *
From (Select Distinct
Securitization
,ReportingDate
,RemittableCollections
From Securitization.dbo.SecuritizationReporting
) src
Pivot ( sum(RemittableCollections) for ReportingDate in ( ' + Stuff((Select Distinct
',' + QuoteName(ReportingDate)
From Securitization.dbo.SecuritizationReporting
Order By 1
For XML Path('')),1,1,'') +' ) ) pvt
'
--Print(#SQL)
Exec(#SQL)
EDIT - Remove NULLS
Declare #NoNulls varchar(max) = Stuff( (
Select Distinct
',' + QuoteName(ReportingDate) +' = IsNull(' + QuoteName(ReportingDate) +',0)'
From Securitization.dbo.SecuritizationReporting
Order By 1
For XML Path('')),1,1,'')
Declare #SQL varchar(max) = '
Select [Securitization]
,' + #NoNulls + '
From (Select Distinct
Securitization
,ReportingDate
,RemittableCollections
From Securitization.dbo.SecuritizationReporting
) src
Pivot ( sum(RemittableCollections) for ReportingDate in ( ' + Stuff((Select Distinct
',' + QuoteName(ReportingDate)
From Securitization.dbo.SecuritizationReporting
Order By 1
For XML Path('')),1,1,'') +' ) ) pvt
'
--Print(#SQL)
Exec(#SQL)

Related

How To Join Pivot Query Output with CTE Output

I Have one CTE Query
WHICH Return This Output :-
I Have Another SQL Statement(With Pivot Query) Which has Following Output :-
I Want to Join Both Output in Single Query output.
I Have Tried to JOIN This Both Query. but, I can't.
I need to show TotalTraffic and UniqueAttendee(both column) output with Pivot table Output.
I want both output in one table format to show it.
my Code is below for both Output:
---output 1 Query(CTE):
;WITH Detailstbl AS (
SELECT
[S].[Title]
,COUNT([VAL].[UserID]) [TotalTraffic]
,COUNT(DISTINCT [VAL].[UserID]) [UniqueAttendee]
FROM [dbo].[AC_Session] [S]
INNER JOIN
[dbo].[AC_ViewActivityLogs] [VAL] ON [S].[SessionID] = [VAL].[ObjectID] AND [VAL].[ObjectName] = 'View Poster Session'
WHERE [S].[IsPosterType] = 1
GROUP BY [S].[Title]
)
SELECT * FROM Detailstbl;
---output 2 Query(Pivot):
DROP TABLE #tempTable
CREATE TABLE #tempTable
(
Title nvarchar(MAX),
TotalTraffic int,
viewdate nvarchar(50)
)
--inserthere
INSERT INTO #tempTable (Title,TotalTraffic,viewdate)
SELECT [S].[Title]
,COUNT([VAL].[UserID]) [TotalTraffic]
,CONVERT(VARCHAR(10), [ViewedOn], 101) AS [ViewedDate]
FROM [dbo].[AC_Session] [S]
INNER JOIN
[dbo].[AC_ViewActivityLogs] [VAL] ON [S].[SessionID] = [VAL].[ObjectID] AND [VAL].[ObjectName] = 'View Poster Session'
WHERE [S].[IsPosterType] = 1
GROUP BY [S].[Title],CONVERT(VARCHAR(10), [ViewedOn], 101)
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX);
SET #cols = STUFF((SELECT distinct ',' + QUOTENAME(c.viewdate)
FROM #tempTable c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
PRINT #cols
set #query = '
SELECT * FROM (
SELECT Title,
' + #cols + ' from
(
select
Title,
TotalTraffic,
viewdate
from #tempTable
) x
pivot
(
max(TotalTraffic)
for viewdate in (' + #cols + ')
) p
) AS x '
execute(#query)
PRINT #query
Below what I have tried but getting error Incorrect syntax near ON
set #query = '
SELECT *
FROM Detailstbl
INNER JOIN(
SELECT * FROM (
SELECT Title,
' + #cols + ' from
(
select
Title,
TotalTraffic,
viewdate
from #tempTable
) x
pivot
(
max(TotalTraffic)
for viewdate in (' + #cols + ')
) p
) AS x ON Detailstbl.Title = x.Title
)'
execute(#query)
PRINT #query
The place where you written the On Clause is incorrect. it should be after the last ')' and you can't use the CTE inside this Dynamic SQL. better try to insert the CTE data into a TempTable Named #Detailstbl
Temp table
SELECT
[S].[Title]
,COUNT([VAL].[UserID]) [TotalTraffic]
,COUNT(DISTINCT [VAL].[UserID]) [UniqueAttendee]
INTO #Detailstbl
FROM [dbo].[AC_Session] [S]
INNER JOIN
[dbo].[AC_ViewActivityLogs] [VAL] ON [S].[SessionID] = [VAL].[ObjectID] AND [VAL].[ObjectName] = 'View Poster Session'
WHERE [S].[IsPosterType] = 1
GROUP BY [S].[Title]
Dynamic SQL
set #query = '
SELECT *
FROM #Detailstbl dtbl
INNER JOIN(
SELECT * FROM (
SELECT Title,
' + #cols + ' from
(
select
Title,
TotalTraffic,
viewdate
from #tempTable
) x
pivot
(
max(TotalTraffic)
for viewdate in (' + #cols + ')
) p
) dt
) x ON dtbl.Title = x.Title '

SQL Server Dynamic Pivoting - Not Usal Pivot With Count

I need to Pivot Questions With Their Answers.The Desired Output of the pivot Query is below and the table structure too.
I have Created the SQL fiddle Here Sql Fiddle. I saw many examples of count with pivot but couldn't find something similar to this.
You simply need some joins to get the base data and a dynamic pivot to show the result in the desired format.
try the following:
drop table if exists #temp
--base table with all details
select s.ID SurveyID, s.SubmittedBy, sq.Question, sa.Answer
into #temp
from #Survey s
join #SurveyMaster sm on sm.ID = s.SurveyMasterID
join #SurveyQuestion sq on sq.SurveyMasterID = s.SurveyMasterID
join #SurveyAnswers sa on sa.SurveyQuestionID = sq.ID and sa.SurveyID = s.ID
--dynamic pivot
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX);
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(c.Question)
FROM #temp c
ORDER BY 1 DESC
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT SurveyID, SubmittedBy, ' + #cols + ' from
(
select SurveyID, SubmittedBy, Question, Answer
from #temp
) x
pivot
(
max(Answer)
for Question in (' + #cols + ')
) p '
--execution
execute(#query)
Please find the db<>fiddle here.
declare #sqlstring as varchar(max) = '';
SELECT
#sqlstring = STUFF((
SELECT distinct
',' + '[' + isnull(sq.Question, '''') + ']'
from
#surveyanswers sa
join
#SurveyQuestion sq
on sq.ID = sa.SurveyQuestionID
join
#survey sv
on sv.SurveyMasterID = sq.SurveyMasterID FOR XML PATH('')), 1, 1, '')
select
sa.SurveyID,
sv.SubmittedBy,
sq.Question,
sa.Answer into ##temp
from
#surveyanswers sa
join
#SurveyQuestion sq
on sq.ID = sa.SurveyQuestionID
join
#survey sv
on sv.SurveyMasterID = sq.SurveyMasterID
set
#sqlstring = 'SELECT SurveyID,SubmittedBy,' + #sqlstring + ' FROM (select * from ##temp ) t ' + ' PIVOT ( ' + ' max(Answer) FOR Question IN (' + #sqlstring + ' ) ) AS pivot_table' execute(#sqlstring);
RESULT:

Pivoting Issue (what am I missing)?

Trying to pivot data and add a calculated column to no avail.
I have tried the enclosed code below but cannot get exactly what I am after.
My table consists of three columns
TABLE_NAME, REPORT_DATE, COUNT_ROWS
For the last two [REPORT_DATE]s, I am trying to show in a pivot the [COUNT_ROWS] for each [TABLE_NAME]
What am I missing? Additionally, how would I go about adding a column subtracting the values between the two dates in the pivot?
DECLARE #cols AS NVARCHAR(MAX)='';
DECLARE #query AS NVARCHAR(MAX)='';
SELECT #cols = #cols + QUOTENAME(REPORT_DATE) + ',' FROM (select DISTINCT TOP 2 REPORT_DATE from account_report order by REPORT_DATE desc) as tmp
select #cols = substring(#cols, 0, len(#cols)) --trim "," at end
set #query =
'SELECT * from
(select [TABLE_NAME], [COUNT_ROWS] from account_report
) src
pivot
(sum([COUNT_ROWS]) for [TABLE_NAME] in (' + #cols + ')
) piv'
execute(#query)
All I am getting from the script is a two column result of the two [REPORT_DATE]s with 1 row showing null values (although my data does include rows)
I bet you are trying to get the following out of the query:
SELECT * from
(select [TABLE_NAME], [COUNT_ROWS], [REPORT_DATE] from account_report
) src
pivot
(sum([COUNT_ROWS]) for [REPORT_DATE] in (' + #cols + ')
) piv
Conversely, if you really want the report name pushed out columnwise then you need to adjust your #cols variable.
SELECT #cols = #cols + QUOTENAME(TABLE_NAME) + ',' FROM (select DISTINCT TOP 2 TABLE_NAME ,REPORT_DATE from account_report order by REPORT_DATE desc) as tmp
select #cols = substring(#cols, 0, len(#cols)) --trim "," at end
set #query =
'SELECT * from
(select [REPORT_DATE], [TABLE_NAME], [COUNT_ROWS] from account_report
) src
pivot
(sum([COUNT_ROWS]) for [TABLE_NAME] in (' + #cols + ')
) piv'
execute(#query)

Normal pivot to convert into dynamic or any other

I have table with this kind of data
ID name St_dt points
1 Mohan 2017-07-10 50
1 Mohan 2017-07-07 30
I want result Set like this
Output :
ID name 2017-07-10 2017-07-07 Difference %
1 Mohan 50 30 20 66.7
I have implemented Pivot function and achieved above result
sample Script :
Select
ID,
name,
[2017-07-10],
[2017-07-07],
[Difference] = [2017-07-10] - [2017-07-07],
case when [2017-07-10] > [2017-07-07]
then cast(round (([2017-07-10] - [2017-07-07]) *1. / [2017-07-07] * 100, 2) as decimal(3,1))
else 0
end as [%]
from (
select ID,name,St_dt,points from Table
)T
PIVOT (MAX(points)FOR St_dt IN ([2017-07-10],[2017-07-07]) )PVT
Up to now this is fine but when I'm trying achieve the same in Dynamic Pivot I'm facing the issue at percentage calculation. How i can achieve in Dynamic.
Hope my question is clear
Please check my dynamic query up to Difference calculation unable to achieve percentage calculation in dynamic
Dynamic Script :
DECLARE #cols AS NVARCHAR(MAX)='';
DECLARE #query AS NVARCHAR(MAX)='';
DECLARE #select_cols AS NVARCHAR(MAX)='';
DECLARE #diff_cols varchar(MAX) = '';
SELECT #cols = #cols + QUOTENAME(St_dt) + ',' FROM (select distinct CONVERT(DATE,St_dt)St_dt from #T
) as tmp ORDER BY St_dt desc
SELECT #cols = substring(#cols, 0, len(#cols))
select #cols
Set #diff_Cols = stuff((SELECT '-Max('+Quotename(CONVERT(DATE, St_dt))+') '
FROM #T
group by St_dt
ORDER BY St_dt DESC
FOR xml path('')) ,1,1,'')
select #diff_cols
Select #query = '
Select ID,name,
'+#cols+',
Difference = '+#diff_cols+'
from (
SELECT ID,name,St_dt,points
FROM #T
)T
PIVOT (MAX(Points)FOR St_dt IN ('+#cols+') )PVT
GROUP BY ID,name,'+#cols+'
'
EXEC (#query)
Try this below ,It may helps you
IF OBJECT_ID('tempdb..#TempTable') IS NOT NULL
DROP TABLE #TempTable
Declare #Table TABLE (ID INT,name VARCHAR(50),St_dt DATE,points INT)
INSERT INTO #Table
SELECT 1,'Harini','2017-07-10',50 Union all
SELECT 1,'Harini','2017-07-07',30
SELECT * INTO #TempTable FROM #Table
DECLARE #Sql NVARCHAR(max)
,#SelectSQL NVARCHAR(max)
,#COlumns NVARCHAR(max)
,#Previousday NVARCHAR(max)
,#Difference NVARCHAR(max)
,#CurrentDay NVARCHAR(max)
SELECT #COlumns=STUFF((SELECT ', '+ QUOTENAME(CAST(St_dt AS VARCHAR(10)))FROM #TempTable GROUP BY St_dt ORDER BY St_dt DESC FOR XML PATH('')),1,1,'')
SELECT #SelectSQL = STUFF((
SELECT ', ' + 'ISNULL( MAX( ' + QUOTENAME(CAST(St_dt AS VARCHAR(10))) +' )'+ ',' + '''0''' + ') AS ' + QUOTENAME(CAST(St_dt AS VARCHAR(10)))
FROM #TempTable GROUP BY St_dt ORDER BY ST_DT DESC
FOR XML PATH('')
), 1, 1, '')
SELECT #CurrentDay=SUBSTRING(#COlumns,CHARINDEX(',',#COlumns)+1,LEN(#COlumns)),#Previousday=SUBSTRING(#COlumns,0,CHARINDEX(',',#COlumns))
SET #Difference=#Previousday+' - '+ #CurrentDay
SET #Sql=N'
SELECT ID,name,'+#SelectSQL+', [Difference]='+#Difference+',
CASE WHEN '+#Previousday+' > '+#CurrentDay+' THEN
CAST(ROUND (('+#Difference+') *1./'+#CurrentDay+'* 100, 2) AS DECIMAL(3,1)) ELSE 0 END AS [%]
FROM (
SELECT ID,name,St_dt,points FROM #TempTable
)Src
PIVOT
(
MAX(points) FOR St_dt IN ('+#COlumns+')
)AS PVT
Group by PVT.ID,PVT.name,
PVT.'+#CurrentDay+',PVT.'+#Previousday+''
PRINT #Sql
EXECute(#Sql)
Result
ID name 2017-07-10 2017-07-07 Difference %
------------------------------------------------------
1 Harini 50 30 20 66.7

SELECT inside pivot incorrect

SSMS is highlighting that something is wrong on the line FOR urlsByFilm.Media_Type_ID IN...
BEGIN
SELECT urlsByFilm.Film_ID, urlsByFilm.Media_Type_ID, urlsByFilm.Media_File_Name
FROM [dbo].[Film_Media_Item] urlsByFilm
PIVOT
(
MAX(urlsByFilm.Media_File_Name)
FOR urlsByFilm.Media_Type_ID IN (SELECT DISTINCT Media_Type_ID FROM [dbo].[Film_Media_Item])
) AS pivot
WHERE API_ID in (#API_IDs)
END
I cannot run this, can you help?
you can't have SQL expression in the IN clause, you need to specify the values.
MAX(urlsByFilm.Media_File_Name)
FOR urlsByFilm.Media_Type_ID IN
(SELECT DISTINCT Media_Type_ID FROM [dbo].[Film_Media_Item])
You need to use dynamic SQL to achieve what you are doing.
your query would like this, with dynamic SQL
DECLARE #cols NVARCHAR(2000)
SELECT #cols = STUFF(( SELECT DISTINCT
'],[' + Media_Type_ID
[dbo].[Film_Media_Item]
ORDER BY '],[' + Media_Type_ID
FOR XML PATH('')
), 1, 2, '') + ']'
DECLARE #query NVARCHAR(4000)
SET #query = N'SELECT Media_File_Name, '+
#cols +'
FROM
(SELECT urlsByFilm.Film_ID, urlsByFilm.Media_Type_ID, urlsByFilm.Media_File_Name
FROM [dbo].[Film_Media_Item] urlsByFilm)p
PIVOT
(
MAX(urlsByFilm.Media_File_Name)
FOR urlsByFilm.Media_Type_ID IN ( '+
#cols +' )
) AS pvt
WHERE API_ID in (#API_IDs)'
EXECUTE(#query)