首页 > 解决方案 > 如果值的总和在两个可能的日期范围之间,则返回 ID,并输出它来自哪个日期范围?

问题描述

我有一个结构与此类似的表:

用户身份 数量 日期
123 50 2021 年 1 月 1 日
234 105 2021 年 2 月 1 日
123 60 2021 年 1 月 15 日
345 70 2021 年 1 月 15 日
456 110 2020 年 12 月 31 日
345 50 2020 年 2 月 15 日

我有两个日期范围,01/01/2021 - 01/31/202102/01/2021 - 02/28/2021 。如果这些日期范围内的总金额 >= 100,我想获取 UserID 的列表,并指定它来自哪个日期范围。

所以在这个例子中,我想要这样的输出:

用户身份 总金额 日期范围
123 110 一月
234 105 二月

用户 ID 345 和 456 将不包括在内,因为它们的总金额仅在日期范围之外达到 >= 100。

在我的代码中,我不确定如何排除 UserID 345,因为从技术上讲,它们的数量 >= 100 来自两个范围内的日期,而不仅仅是一个范围。

如果仅在日期范围内求和,我会遇到麻烦,并且我不确定如何指定它来自哪个日期范围:

SELECT
   UserID
   ,SUM(amount)
FROM table
WHERE
   date BETWEEN '01-01-2021' AND '01-31-2021' OR
   date BETWEEN '02-01-2021' AND '02-28-2021'
GROUP BY 
   UserID
HAVING SUM(amount) >= 100

标签: sqlsql-servertsql

解决方案


如果您的日期范围是几个月,您可以加入这些范围,然后按用户聚合:

select min(range_name), user_name, sum(amount)
from t join
     (values ('2021-01-01', '2021-01-31', 'January'),
             ('2021-02-01', '2021-02-28', 'February')
     ) v(range_start, range_end, range_name)
     on t.date >= v.range_start and t.date <= v.range_end        
group by userid
having count(distinct range_name) = 1 and
       sum(amount) > 100;

having子句通过范围数和数量来限制结果。

如果您只想要特定日期之间的几个月,我会将其简化为:

select datepart(month, min(date)), userid, sum(amount)
from t
where date >= '2021-01-01' and date < '2021-03-01'
group by userid
having count(distinct month(date)) = 1 and
       sum(amount) > 100;

推荐阅读