【发布时间】:2019-05-29 19:22:26
【问题描述】:
我已经这样做了:
;WITH a AS
(
SELECT
a.account
,index_num_date = 'date ' + CONVERT(VARCHAR(30), DENSE_RANK() OVER ( PARTITION BY a.account ORDER BY ratechangedate ))
,index_num_rate = 'rate ' + CONVERT(VARCHAR(30), DENSE_RANK() OVER ( PARTITION BY a.account ORDER BY ratechangedate ))
,ratechangedate
,new_noterate
FROM MARS_DW.dbo.vw_GTMScheduledRateAndPaymentChangesWithAccountNumber_Archive a
INNER JOIN
(
SELECT *
FROM mars..vw_loans
WHERE loanstatus <> 'bk payment plan'
) b ON a.account = b.account
WHERE archivedate = '5/20/2019'
)
,q1 AS
(
SELECT DISTINCT
account
,ratechangedate
,index_num_date
FROM a
)
,q2 AS
(
SELECT DISTINCT
account
,new_noterate
,index_num_rate
FROM a
)
,datepivot AS
(
SELECT DISTINCT
account
,[date 1]
,[date 2]
,[date 3]
,[date 4]
,[date 5]
,[date 6]
,[date 7]
,[date 8]
,[date 9]
,[date 10]
,[date 11]
,[date 12]
,[date 13]
FROM q1
PIVOT
(
MIN(ratechangedate)
FOR index_num_date IN ( [date 1]
,[date 2]
,[date 3]
,[date 4]
,[date 5]
,[date 6]
,[date 7]
,[date 8]
,[date 9]
,[date 10]
,[date 11]
,[date 12]
,[date 13]
)
) pvt1
)
,ratepivot AS
(
SELECT DISTINCT
account
,[rate 1]
,[rate 2]
,[rate 3]
,[rate 4]
,[rate 5]
,[rate 6]
,[rate 7]
,[rate 8]
,[rate 9]
,[rate 10]
,[rate 11]
,[rate 12]
,[rate 13]
FROM q2
PIVOT
(
MIN(new_noterate)
FOR index_num_rate IN ( [rate 1]
,[rate 2]
,[rate 3]
,[rate 4]
,[rate 5]
,[rate 6]
,[rate 7]
,[rate 8]
,[rate 9]
,[rate 10]
,[rate 11]
,[rate 12]
,[rate 13]
)
) pvt2
)
SELECT
a.Account
,[date 1]
,[rate 1]
FROM datepivot a
LEFT JOIN ratepivot b ON a.Account = b.Account
这给了我这个
但这不是动态的,我的 Microsoft 2016 版不允许我使用各种帖子中推荐的 Fiddle 东西。因此建议我使用Coalesce() 函数,但我不知道如何使后者动态化。任何帮助(不是指某些帖子)都会有帮助。
更新:
在评论之后我尝试了这个:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX);
SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(c.Account)
FROM MARS_DW.[dbo].[vw_GTMScheduledRateAndPaymentChangesWithAccountNumber_Archive] c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT Account, ' + @cols + ' from
(
select Account
, ratechangedate
, new_noterate
from MARS_DW.[dbo].[vw_GTMScheduledRateAndPaymentChangesWithAccountNumber_Archive]
) x
pivot
(
min(ratechangedate)
for category in (' + @cols + ')
) p '
但得到这个错误:
Msg 1056, Level 15, State 1, Line 37
The number of elements in the select list exceeds the maximum allowed number of 4096 elements.
Msg 102, Level 15, State 1, Line 43
Incorrect syntax near 'x'.
更新:
我试过这个来限制数量
DECLARE @cols AS NVARCHAR(MAX);
DECLARE @query AS NVARCHAR(MAX);
SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(c.RateChangeDate)
FROM MARS_DW.[dbo].[vw_GTMScheduledRateAndPaymentChangesWithAccountNumber_Archive] c
WHERE c.ArchiveDate = '5/21/2019' AND c.AppliedDate > '1/2/2018'
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT Account, ' + @cols + ' from
(
select Account
, ratechangedate
, new_noterate
from MARS_DW.[dbo].[vw_GTMScheduledRateAndPaymentChangesWithAccountNumber_Archive]
) x
pivot
(
min(ratechangedate)
for category in (' + @cols + ')
) p
pivot
(
min(new_noterate)
for category in (' + @cols + ')
)
'
execute(@query)
但我收到此错误:
Msg 102, Level 15, State 1, Line 52
Incorrect syntax near ')'.
这里要求的是数据表中的前 10 名
【问题讨论】:
-
要使您的数据透视动态化,您将使用动态 sql。 Fiddle 通常是对dbfiddle.uk 的引用。 @Taryn--DBA at SO-- 在this post 中有一个很好的答案。你有什么不明白的地方?
-
您使用
Account而不是ratechangedate来填充@cols。 -
不要使用
execute(@query)作为最后的语句,使用print(@query)并找出你的语法错误。 -
第二个
PIVOT子句缺少别名导致语法错误。但是,如果您为其添加别名,您将收到一个新错误,说明第二个PIVOT中的列名已在第一个PIVOT中指定(因为您使用相同的@cols变量来构建旋转的列名称)。如果您可以提供 vw_GTMScheduledRateAndPaymentChangesWithAccountNumber_Archive 的表定义(即列名、数据类型、一些示例原始数据行),那将非常非常有帮助。 -
@digital.aaron 我对 SQL 完全陌生,你说的表定义是什么意思?大多数数据类型是浮点数、日期和 varchars
标签: sql sql-server