我想将日期值从列转置为行,并根据各自的公司名称将相关数据填充在它们下面。但我需要跨多年的连续的每日时间序列,即使有空白(因此第 1 列 = 公司名称,第 2 列是第 N 天,第 3 列是 N+1,第 4 列是 N+2 等)。
我一直在使用下面的查询,但是当我复制“SUM(CASE WHEN...”大约 4000 次以获取自 2013 年以来的连续每日日期(通过从 Excel 复制/粘贴)并展开“P.FirmName in ...”到大约 1000 个条目,查询运行速度比 slug 慢。
在将此类查询扩展为包含约 4000 个“SUM(CASE WHEN...”日期和约 1000 个“P.FirmName in...”值后,我可以做些什么来优化这种类型的查询吗?
提前谢谢您!
SELECT P.FirmName,
SUM(CASE WHEN [DATE] = '2023-11-30' THEN [TOTAL] END) as '2023-11-30'
SUM(CASE WHEN [DATE] = '2023-12-01' THEN [TOTAL] END) as '2023-12-01'
SUM(CASE WHEN [DATE] = '2023-12-02' THEN [TOTAL] END) as '2023-12-02'
SUM(CASE WHEN [DATE] = '2023-12-03' THEN [TOTAL] END) as '2023-12-03'
FROM [Total].[Database] S
Left Join [Product].[Database] P ON S.Product = P.Product
Where FirmLocation not in (-1,-2,-3) and P.FirmName in (Apple, Banana, Cherry)
Group by P.FirmName
查询运行,但是——我怎么强调都不为过——当扩展到包括所有日期和公司名称时,查询速度非常慢。
根据提供最小可重现示例的请求,我更新了上述查询,并在每个表中包含了相关数据的屏幕截图以及所需的结果:
使用数据透视、动态查询和
STUFF
从 DATE
s: 创建逗号分隔的字符串
DROP TABLE IF EXISTS #temp;
SELECT FirmName, SUM(TOTAL) TOTAL, CAST([DATE] AS NVARCHAR(MAX)) as Date
INTO #temp
FROM [Total].[Database] S
Left Join [Product].[Database] P ON S.Product = P.Product
Where FirmLocation not in (-1,-2,-3) and P.FirmName in (Apple, Banana, Cherry)
GROUP BY FirmName, Date;
DECLARE @dates NVARCHAR(MAX) = STUFF(
(
SELECT ',[' + Date + ']'
FROM
(
SELECT DISTINCT Date FROM #temp
)t
FOR XML PATH (''))
, 1, 1, '');
DECLARE @query NVARCHAR(MAX) = 'SELECT FirmName, ' + @dates + '
FROM
(
SELECT [Date],FirmName, TOTAL
FROM #temp
) AS SourceTable
PIVOT
(
SUM(TOTAL)
FOR [Date] IN (' + @dates + ')
) AS PivotTable'
EXEC(@query)