利用多年的每日数据优化 SQL 中的列转置

问题描述 投票:0回答:1

我想将日期值从列转置为行,并根据各自的公司名称将相关数据填充在它们下面。但我需要跨多年的连续的每日时间序列,即使有空白(因此第 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

查询运行,但是——我怎么强调都不为过——当扩展到包括所有日期和公司名称时,查询速度非常慢。


根据提供最小可重现示例的请求,我更新了上述查询,并在每个表中包含了相关数据的屏幕截图以及所需的结果:

Total Database Table Example

Product Database Table Example

Desired Results

sql sql-server performance pivot query-optimization
1个回答
0
投票

使用数据透视、动态查询和

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)

这是 AdventureWorks 数据库的可执行查询

© www.soinside.com 2019 - 2024. All rights reserved.