我创建了带有硬编码列名的数据透视表。数据透视表只是按数量(当月+ 11个月前)保持滚动销售总额。
这是我第一次正确使用PIVOT函数,并且代码运行正常。
SELECT
Item_Code_Desc,
ISNULL([Current],0) AS [Current],
ISNULL([1],0) AS [1],
ISNULL([2],0) AS [2],
ISNULL([3],0) AS [3],
ISNULL([4],0) AS [4],
ISNULL([5],0) AS [5],
ISNULL([6],0) AS [6],
ISNULL([7],0) AS [7],
ISNULL([8],0) AS [8],
ISNULL([9],0) AS [9],
ISNULL([10],0) AS [10],
ISNULL([11],0) AS [11]
FROM
(SELECT
CONCAT(ST.Code,' - ', ST.Description_1) AS Item_Code_Desc,
STT.ActualQuantity AS Qty,
CASE
WHEN MONTH(STT.TxDate) = MONTH(GETDATE()) THEN 'Current'
WHEN MONTH(STT.TxDate) = MONTH(DATEADD(MONTH, -1, GETDATE())) THEN '1'
WHEN MONTH(STT.TxDate) = MONTH(DATEADD(MONTH, -2, GETDATE())) THEN '2'
WHEN MONTH(STT.TxDate) = MONTH(DATEADD(MONTH, -3, GETDATE())) THEN '3'
WHEN MONTH(STT.TxDate) = MONTH(DATEADD(MONTH, -4, GETDATE())) THEN '4'
WHEN MONTH(STT.TxDate) = MONTH(DATEADD(MONTH, -5, GETDATE())) THEN '5'
WHEN MONTH(STT.TxDate) = MONTH(DATEADD(MONTH, -6, GETDATE())) THEN '6'
WHEN MONTH(STT.TxDate) = MONTH(DATEADD(MONTH, -7, GETDATE())) THEN '7'
WHEN MONTH(STT.TxDate) = MONTH(DATEADD(MONTH, -8, GETDATE())) THEN '8'
WHEN MONTH(STT.TxDate) = MONTH(DATEADD(MONTH, -9, GETDATE())) THEN '9'
WHEN MONTH(STT.TxDate) = MONTH(DATEADD(MONTH, -10, GETDATE())) THEN '10'
WHEN MONTH(STT.TxDate) = MONTH(DATEADD(MONTH, -11, GETDATE())) THEN '11'
ELSE '0'
END AS [Period]
FROM
_bvSTTransactionsFull AS STT
INNER JOIN
StkItem AS ST ON STT.AccountLink = ST.StockLink
WHERE
STT.TxDate >= DATEADD(MONTH, -11, DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0))
AND STT.Module = 'AR') AS P
PIVOT
(SUM(P.Qty)
FOR P.Period IN ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[Current])
) AS PVT
为使输出更具动态性,我想将月份和年份显示为字段标题,而不只是显示1,2,3等。
为此,我先取出原始的CASE,然后使用CONCAT函数获得所需的结果
CONCAT(DATENAME(MONTH,STT.TxDate),' ',YEAR(STT.TxDate)) AS [Period],
现在,子查询以“ mmmm yyyy”格式显示交易日期,我希望表格以此为中心。我确实想知道在到达终点时将如何执行此操作,因为列名不再是硬编码的。
尝试
PIVOT (
SUM(P.Qty)
FOR CONCAT(DATENAME(MONTH,P.TxDate),' ',YEAR(P.TxDate))
) AS PVT
我做了很多其他的研究,发现这个过程比我想象的要复杂一些。
我以前没有使用过STUFF和FOR XML PATH。我试图将以上内容转换为我在网上找到的示例。但是我正在尝试尝试,因为我不了解我要做的事情的核心逻辑。
请我不仅在如何使轴动态变化方面获得帮助,还可能需要一些注释以进一步了解正在发生的事情。非常感谢您的帮助!
尝试后
这是我做对的尝试:
DECLARE
@Cols NVARCHAR(MAX),
@Query NVARCHAR(MAX),
@Module NVARCHAR = 'AR'
SELECT
@Cols = STUFF((SELECT DISTINCT ',' + 'CONCAT(DATENAME(MONTH, STT.TxDate),,YEAR(STT.TxDate))' + QUOTENAME(NAME)
FROM _bvSTTransactionsFull AS STT
WHERE STT.Module = 'AR'
FOR XML PATH (''), TYPE).VALUE('.','NVARCHAR(MAX)'),1,1,'')
SELECT
@Query = '
SELECT
Item_Code,
Item_Desc,
' +''''+ @Cols + '''''
FROM
(SELECT
ST.Code AS Item_Code,
ST.Description_1 AS Item_Desc,
STT.ActualQuantity AS Qty,
CONCAT(DATENAME(MONTH, STT.TxDate),,YEAR(STT.TxDate)) AS [Period]
FROM
_bvSTTransactionsFull AS STT
INNER JOIN
StkItem AS ST ON STT.AccountLink = ST.StockLink
WHERE
STT.TxDate >= DATEADD(MONTH, -13, DATEADD(MONTH, DATEDIFF(MONTH, 0,
GETDATE()), 0))
AND STT.Module = '+ @Module +') AS P
PIVOT
(SUM(P.Qty)
FOR P.Period IN ('+@cols+')
) AS PVT '
PRINT @Query
EXEC (@Query)
但是我遇到以下错误:
信息207,第16级,状态1,第7行 列名称“ NAME”无效。
我在这里去哪里?
答案 0 :(得分:0)
已解决:)
DECLARE
@Cols1 VARCHAR(MAX),
@Cols2 VARCHAR(MAX),
@Query VARCHAR(MAX),
@Period VARCHAR(MAX) = -12 ; --/ Select number of months to view back on (excluding current month) \--
SELECT
@Cols1 = STUFF((SELECT DISTINCT ',' +'ISNULL('+ QUOTENAME(CONCAT(DATENAME(MONTH, S.TxDate),' ',YEAR(S.TxDate)))+',0) AS' + QUOTENAME(CONCAT(DATENAME(MONTH, S.TxDate),' ',YEAR(S.TxDate)))
FROM _bvSTTransactionsFull AS S
WHERE S.Module = 'AR' AND S.TxDate > = DATEADD(MONTH, -13, DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0))
FOR XML PATH (''), TYPE).value('.','NVARCHAR(MAX)'),1,1,'') --/ allows the first SELECT fields to have the ISNULL function and Alias \--
SELECT
@Cols2 = STUFF((SELECT DISTINCT ',' + QUOTENAME(CONCAT(DATENAME(MONTH, S.TxDate),' ',YEAR(S.TxDate)))
FROM _bvSTTransactionsFull AS S
WHERE S.Module = 'AR' AND S.TxDate > = DATEADD(MONTH, -13, DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0))
FOR XML PATH (''), TYPE).value('.','NVARCHAR(MAX)'),1,1,'') --/ becasue of the need for ISNULL above, second @Cols needed for the Pivot (pivot cannot have ISNULL in it) \--
SELECT
@Query =
'SELECT
Item_Code_Desc,
'+@Cols1+'
FROM
(SELECT
CONCAT(ST.Code,'' - '', ST.Description_1) AS Item_Code_Desc,
STT.ActualQuantity AS Qty,
CONCAT(DATENAME(MONTH, STT.TxDate),'' '',YEAR(STT.TxDate)) AS [Period]
FROM
_bvSTTransactionsFull AS STT
INNER JOIN
StkItem AS ST ON STT.AccountLink = ST.StockLink
WHERE
STT.TxDate >= DATEADD(MONTH, '+@Period+', DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0))
AND STT.Module = ''AR'') AS P
PIVOT
(SUM(P.Qty)
FOR P.Period IN ('+@cols2+')
) AS PVT '
PRINT @Query
EXEC (@Query)
答案 1 :(得分:0)
上面的结果是正确的,但是您不会按正确的日期对列进行排序...
以下内容可以满足您的需求:
DECLARE
@Cols1 VARCHAR(MAX),
@Cols2 VARCHAR(MAX),
@Query VARCHAR(MAX),
@Period VARCHAR(MAX) = -13 ; --/ Select number of months to view back on (excluding current month) \--
declare @tmptbl table (PeriodDate datetime, col1 varchar(100), col2 varchar(100))
insert into @tmptbl (PeriodDate, col1, col2)
SELECT DISTINCT dPeriodDate,'ISNULL('+ QUOTENAME(CONCAT(DATENAME(MONTH, dPeriodDate),' ',YEAR(dPeriodDate)))+',0) AS' + QUOTENAME(CONCAT(DATENAME(MONTH, dPeriodDate),' ',YEAR(dPeriodDate))) col1
, QUOTENAME(CONCAT(DATENAME(MONTH, dPeriodDate),' ',YEAR(dPeriodDate))) col2
FROM _bvSTTransactionsFull AS S join _etblPeriod p on EOMONTH(s.TxDate) = p.dPeriodDate
WHERE S.Module = 'AR' AND S.TxDate > = DATEADD(MONTH, -13, DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0))
SELECT
@Cols1 = STUFF((SELECT ',' + col1
FROM @tmptbl order by PeriodDate
FOR XML PATH (''), TYPE).value('.','NVARCHAR(MAX)'),1,1,'') --/ allows the first SELECT fields to have the ISNULL function and Alias \--
SELECT
@Cols2 = STUFF((SELECT ',' + col2
FROM @tmptbl order by PeriodDate
FOR XML PATH (''), TYPE).value('.','NVARCHAR(MAX)'),1,1,'') --/ becasue of the need for ISNULL above, second @Cols needed for the Pivot (pivot cannot have ISNULL in it) \--
SELECT
@Query =
'SELECT
Item_Code_Desc,
'+@Cols1+'
FROM
(SELECT
CONCAT(ST.Code,'' - '', ST.Description_1) AS Item_Code_Desc,
STT.ActualQuantity AS Qty,
CONCAT(DATENAME(MONTH, STT.TxDate),'' '',YEAR(STT.TxDate)) AS [Period]
FROM
_bvSTTransactionsFull AS STT
INNER JOIN
StkItem AS ST ON STT.AccountLink = ST.StockLink
WHERE
STT.TxDate >= DATEADD(MONTH, '+@Period+', DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0))
AND STT.Module = ''AR'') AS P
PIVOT
(SUM(P.Qty)
FOR P.Period IN ('+@cols2+')
) AS PVT '
PRINT @Query
EXEC (@Query)
我把我所做的更改都用小写字母写给大家,以查看更改...