2015-04-20 4 views
0

У меня есть статический сводный запрос, который отслеживает историческую цену (см. Ниже); это объединение всей одной таблицы текущих данных, одной таблицы исторических данных и одной связанной таблицы.Динамический SQL Pivot Query with Union Все

Я хотел бы преобразовать его в динамический SQL-сводный запрос, так что мне не нужно вручную обновлять даты заголовка столбца все время, но у меня возникают проблемы с этим. Данные поступают из системы учета (Microsoft Dynamics), работающей на SQL Server, и из-за системных ограничений я не могу использовать ansi nulls/paddings/warnings и также не могу использовать цитируемые идентификаторы. Есть ли другой способ создать динамический sql-запрос?

Вот мой текущий запрос. Я хочу заменить даты месяца с динамическим 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

Вы можете использовать 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, '[email protected]+' 
FROM ST 
PIVOT 
(
SUM(PERDBLNC) 
FOR DATE1 IN ('[email protected]+') 
) AS PVT 
WHERE ACTNUMBR_1 = ?' 
--PRINT IT TO SEE WHAT IT'S DONE-- 
PRINT @SQL 
--EXECUTE IT-- 
EXEC (@SQL) 
+0

Спасибо за помощь. К сожалению, я использую внешнее подключение к данным в Excel, чтобы вернуть данные для возврата данных из базы данных, что не позволяет использовать временные таблицы. – krstn17

+0

В вашем исходном сообщении говорится, что данные поступают из Dynamics CRM, работающего под SQL Server ... Нет никаких ограничений ни на что, если вы будете выглядеть достаточно тяжело, многие вещи, которые, как я полагал, были невозможны, теперь возможны благодаря упорству и исследованиям других людей. Я бы рекомендовал, что вы не использовали Excel в качестве внешнего источника данных, а скорее использовали SQL Server и SSRS для создания отчета о матрице. Это намного проще, чем вы пытаетесь сделать здесь. –