如何简化包含子查询的重复CASE语句

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

我构建了一个满足以下逻辑的查询:

  1. 对于当前月份,从加入材料的表 H 中提取当前值。
  2. 对于过去的 2023 个月,从历史表 HHistory 中提取在材料和第 Mth 上连接的值(HHistory 是表 H 的每月备份,带有附加的第 Mth 列。月份可追溯到 2023 年 1 月)。
  3. 对于 2023 年之前的所有其他月份,无论第几个月,都从 HHistory 中提取最早的非空值。

这对于 SqFt 来说非常有效,并且运行时间不到一秒。但是,我现在需要将其扩展到其他 30 个领域(劳动力、体重等),一旦我尝试这样做,运行时间就会迅速增加。我想知道是否可以在添加字段时重组 CASE 甚至删除子查询以提高性能。我相信子查询是导致性能不佳的原因,但我还没有弄清楚如何在没有子查询的情况下获取最旧的值。有什么想法吗?

SELECT 
    I.Mth, I.Material,

    - - -
    SUM(I.Units) *  CASE 
                        WHEN MONTH(I.Mth) = MONTH(GETDATE()) AND YEAR(I.Mth) = YEAR(GETDATE()) THEN H.SqFt 
                        WHEN YEAR(I.Mth) >= 2023 THEN HHistory.SqFt 
                        ELSE (SELECT TOP 1 SqFt FROM HHistory Sub WHERE Sub.Material = I.Material AND Sub.SqFt IS NOT NULL ORDER BY Sub.KeyID) 
                    END AS [Total SqFt]
    - - - This section gets repeated for 30 different fields

FROM I
    LEFT JOIN H ON I.Material = H.Material 
    LEFT JOIN HHistory ON I.Mth = HHistory.Mth AND I.Material = HHistory.Material
GROUP BY I.Material, I.Mth, H.SqFt, HHistory.SqFt 
sql sql-server subquery
1个回答
-2
投票

尝试尽可能减少通话次数 例如,您可以使用变量来避免所有 getdate() 调用,他的方式是您只调用一次,这样您就可以一次性处理该函数。

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