使用Union All的动态SQL数据透视查询

时间:2015-04-20 22:23:58

标签: sql-server pivot dynamic-sql microsoft-dynamics

我有一个跟踪历史定价的静态数据透视查询(见下文);它是一个当前数据表,一个历史数据表和一个相关表的联合。

我想将其转换为动态SQL数据透视查询,以便我不必手动更新列标题日期,但我遇到了问题。数据来自在SQL Server上运行的会计系统(Microsoft Dynamics),由于系统限制,我无法使用ansi nulls / paddings / warnings,也无法使用带引号的标识符。有没有其他方法可以创建动态sql pivot查询?

这是我当前的查询。我想用动态sql替换月末日期。我只能查看对数据的访问权限。

SELECT ACTDESCR AS "ACCT NAME", concat(right(actnumbr_2,2), actnumbr_3) as PLU, [3/31/2015], [2/28/2015], [1/31/2015], [12/31/2015], [11/30/2014], [10/31/2014], [9/30/2014], [8/31/2014], [7/31/2014], [6/30/2014], [5/31/2014], [4/30/2014], [3/31/2014], [2/28/2014], [1/31/2014]
FROM
(SELECT A.ACTDESCR, EOMONTH(DATEFROMPARTS(B.YEAR1,B.PERIODID,1),0) AS DATE1, A.actnumbr_2, a.actnumbr_3, B.PERDBLNC, A.ACTNUMBR_1
FROM TEST.dbo.table1 AS A   

LEFT OUTER JOIN TEST.dbo.TABLE2 AS b
ON (a.ACTINDX = b.ACTINDX)

UNION ALL

SELECT A.ACTDESCR, EOMONTH(DATEFROMPARTS(C.YEAR1,C.PERIODID,1),0) AS DATE1, A.actnumbr_2, a.actnumbr_3, C.PERDBLNC, A.ACTNUMBR_1
FROM TEST.dbo.TABLE1 AS A

LEFT OUTER JOIN TEST.dbo.TABLE3 AS C
ON (a.ACTINDX = C.ACTINDX)
) AS ST

PIVOT
(
SUM(PERDBLNC)
FOR DATE1 IN ([3/31/2015], [2/28/2015], [1/31/2015], [12/31/2015], [11/30/2014], [10/31/2014], [9/30/2014], [8/31/2014], [7/31/2014], [6/30/2014], [5/31/2014], [4/30/2014], [3/31/2014], [2/28/2014], [1/31/2014])

) AS PVT

WHERE ACTNUMBR_1 = ?

1 个答案:

答案 0 :(得分:1)

您可以将T-SQL与动态SQL一起使用:

--VARIABLE TO HOLD DATES--
DECLARE @DATES NVARCHAR(500)
--VARIABLE TO HOLD CODE--
DECLARE @SQL NVARCHAR(MAX)

--TEMP TABLE TO FIND DISTINCT DATES--
CREATE #DATES (COLUMNVALS NVARCHAR(10))

--INSERT DISTINCT DATES INTO TEMP TABLE--
INSERT INTO #DATES
SELECT DISTINCT DATE1 FROM (
SELECT EOMONTH(DATEFROMPARTS(YEAR1,PERIODID,1),0) AS DATE1
FROM TEST.DBO.TABLE2
UNION ALL
SELECT EOMONTH(DATEFROMPARTS(YEAR1,PERIODID,1),0) AS DATE1
FROM TEST.DBO.TABLE3)

--CONCAT DATES INTO SELECT LIST--
SET @DATES = COALESCE(@DATES+', ','') + '[' + DATE1 + ']' FROM #DATES

--CREATE THE SELECT STATEMENT--
SELECT @SQL = '
;WITH ST AS (
SELECT A.ACTDESCR, EOMONTH(DATEFROMPARTS(B.YEAR1,B.PERIODID,1),0) AS DATE1, A.ACTNUMBR_2, A.ACTNUMBR_3, B.PERDBLNC, A.ACTNUMBR_1
FROM TEST.DBO.TABLE1 AS A   
LEFT OUTER JOIN TEST.DBO.TABLE2 AS B
ON A.ACTINDX = B.ACTINDX
UNION ALL
SELECT A.ACTDESCR, EOMONTH(DATEFROMPARTS(C.YEAR1,C.PERIODID,1),0) AS DATE1, A.ACTNUMBR_2, A.ACTNUMBR_3, C.PERDBLNC, A.ACTNUMBR_1
FROM TEST.DBO.TABLE1 AS A
LEFT OUTER JOIN TEST.DBO.TABLE3 AS C
ON A.ACTINDX = C.ACTINDX)
SELECT ACTDESCR AS "ACCT NAME", CONCAT(RIGHT(ACTNUMBR_2,2), ACTNUMBR_3) AS PLU, '+@DATES+'
FROM ST
PIVOT
(
SUM(PERDBLNC)
FOR DATE1 IN ('+@DATES+')
) AS PVT
WHERE ACTNUMBR_1 = ?'
--PRINT IT TO SEE WHAT IT'S DONE--
PRINT @SQL
--EXECUTE IT--
EXEC (@SQL)