避免在 SQL 分组中固定筛选日期

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

考虑代码:

Declare @A table (
    SoldDate Date,
    ItemName varchar(100),
    Cost float
)

Insert into @A VALUES 
('2022-01-19','Item A',0.156),
('2022-05-02','Item B',1.4752),
('2022-09-13','Item C',0.782155),
('2022-12-07','Item D',2.4260),
('2023-01-11','Item A',0.1),
('2023-04-14','Item B',-0.1546),
('2023-05-22','Item C',19.152),
('2023-06-18','Item D',0.000175),
('2023-07-03','Item A',1),
('2023-09-29','Item B',23.41),
('2023-10-19','Item C',7.24),
('2023-11-10','Item D',13.4)

Select
ItemName, Sum(Cost) As [Sum Of Cost], iif(SoldDate >= '01-Nov-2022','2023','2022') as Year
From @A

Group By
ItemName, iif(SoldDate >= '01-Nov-2022','2023','2022')

固定日期是问题;我想将其更改为动态计算(最新 SoldDate 减去一年),但 SQL 正在外部应用程序中使用,该应用程序不允许临时变量。

我尝试过动态查询:

Select
ItemName, Sum(Cost) As [Sum Of Cost], iif(SoldDate >= dateadd(year,-1,max(SoldDate)),'2023','2022') as Year
From @A

Group By
ItemName, iif(SoldDate >= dateadd(year,-1,max(SoldDate)),'2023','2022')

但我收到错误

不能在用于 GROUP BY 子句的分组依据列表的表达式中使用聚合或子查询。

是否可以将此作为一个查询的一部分?

sql sql-server dynamic
1个回答
0
投票

如果您的查询在 2023 年的大部分时间里都按预期运行,但最近停止提供所需的结果,我认为您不需要重新定义year-window。您更有可能需要使用类似

YEAR(DATEADD(month, 2, SoldDate))
的内容来概括 FY 计算。

此计算可以包含在

CROSS APPLY
中,以避免定义两次。

Select
    ItemName,
    Sum(Cost) As [Sum Of Cost],
    FY.Year
From @A
Cross Apply (Select year(dateadd(month, 2, SoldDate)) As Year) FY
Group By
    ItemName,
    FY.Year

结果:

商品名称 费用总和 年份
项目A 0.156 2022
B 项 1.4752 2022
项目C 0.782155 2022
项目A 1.1 2023
B 项 23.2554 2023
项目C 26.392 2023
项目D 2.426175 2023
项目D 13.4 2024

请注意,销售额现在跨越三个财政年度:

  • 2022 财年 - 2021 年 11 月至 2022 年 10 月
  • 2023 财年 - 2022 年 11 月至 2023 年 10 月
  • 2024 财年 - 2023 年 11 月至 2024 年 10 月

如果您确实需要使用基于

max(SoldDate)
的滑动年份定义,您可以在CTE或子选择中计算一次
max(SoldDate)
。 (如果
SoldDate
列已建立索引,这将是一个快速而简单的索引查找。)然后,您可以使用它来计算“销售年份”或通过将日历年与条件 +1 相结合来计算“销售年份”或任何您可能称之为的名称。基于日期的 MM/DD 部分的比较进行调整..

Select
    A.ItemName,
    Sum(A.Cost) As [Sum Of Cost],
    SY.Year
From @A A
Cross Apply (
    Select year(A.SoldDate)
        + IIF(CONVERT(CHAR(5), A.SoldDate) > CONVERT(CHAR(5), M.MaxSoldDate), 1, 0)
        As Year
    From (Select max(soldDate) As MaxSoldDate From @A) M
) SY
Group By
    A.ItemName, SY.Year

我变了

结果:

商品名称 费用总和 年份
项目A 0.156 2022
B 项 1.4752 2022
项目C 0.782155 2022
项目D 2.426 2022
项目A 1.1 2023
B 项 23.2554 2023
项目C 26.392 2023
项目D 13.400175 2023

参见这个数据库<>小提琴

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