【问题标题】:Group By with Case statement?分组依据与案例声明?
【发布时间】:2023-03-02 21:11:01
【问题描述】:

我需要找到 3 天范围内的 number 订单总和。想象一下这样的桌子

订单      日期
300     2015 年 1 月 5 日
200     2015 年 1 月 6 日
150     2015 年 1 月 7 日
250     2015 年 1 月 5 日
400     2015 年 1 月 4 日
350     2015 年 1 月 3 日
50       2015 年 1 月 2 日
100     2015 年 1 月 8 日

所以我想创建一个按子句分组,它将任何具有相同月份、年份和日期的日期从 1-3 或 4-6、7-9 等分组,直到我达到 30 天。

似乎我想做的是为包含某种类型的循环的分组创建一个案例,但我不确定这是否是最好的方法,或者是否可以将它们组合起来。

另一种方法可能是创建一个 case 语句,该语句创建一个分配组号的新列,然后按该数字、月份和年份进行分组。

不幸的是,我从未使用过 case 语句,所以我不确定哪种方法最好,或者如何执行它们,尤其是在循环中。

编辑:我正在使用 Access,所以看起来我将使用 IIF 而不是 Case

【问题讨论】:

  • 您真的在使用访问权限吗? Access 没有 case 语句。虽然它有 IIF
  • 如果 Access 具有分析功能,那将是理想的,但它没有。话虽如此,看起来您实际上并不想要超过 3 天的订单?这将是每行上的订单计数,该行的日期和前 2 天(在滚动的基础上,有重叠)。你不想重叠,对吗?那么第 1 天到第 3 天会是一个小组吗?第 4 天将是新组的开始(不包括第 3 天和第 2 天)?
  • 是的,我不想重叠,第 4 天将是一个新组的开始。我会为该月的第 31 天创建一些条件语句,以便将其包含在最后一组中。
  • 你会一次运行这个一个月吗?
  • 不,我不知道你为什么要问。

标签: sql ms-access


【解决方案1】:

以下内容如何:

订单计数

select      year([Date]) as yr,
            month([Date]) as monthofyr,
            sum(iif((day([Date])>=1) and (day([Date])<=3),1,0)) as days1to3,
            sum(iif((day([Date])>=4) and (day([Date])<=6),1,0)) as days4to6,
            sum(iif((day([Date])>=7) and (day([Date])<=9),1,0)) as days7to9,
            sum(iif((day([Date])>=10) and (day([Date])<=12),1,0)) as days10to12,
            sum(iif((day([Date])>=13) and (day([Date])<=15),1,0)) as days13to15,
            sum(iif((day([Date])>=16) and (day([Date])<=18),1,0)) as days16to18,
            sum(iif((day([Date])>=19) and (day([Date])<=21),1,0)) as days19to21,
            sum(iif((day([Date])>=22) and (day([Date])<=24),1,0)) as days22to24,
            sum(iif((day([Date])>=25) and (day([Date])<=27),1,0)) as days25to27,
            sum(iif((day([Date])>=28) and (day([Date])<=31),1,0)) as days28to31
from        tbl
where       [Date] between x and y
group by    year([Date]),
            month([Date])

将 x 和 y 替换为您的日期范围。

最后一组是当月的第 28 天到第 31 天,因此对于有 31 天的月份,它可能包含 4 天的订单。

以上是订单计数。

如果您想要订单金额的总和:

订单金额总和

select      year([Date]) as yr,
            month([Date]) as monthofyr,
            sum(iif((day([Date])>=1) and (day([Date])<=3),order,0)) as days1to3,
            sum(iif((day([Date])>=4) and (day([Date])<=6),order,0)) as days4to6,
            sum(iif((day([Date])>=7) and (day([Date])<=9),order,0)) as days7to9,
            sum(iif((day([Date])>=10) and (day([Date])<=12),order,0)) as days10to12,
            sum(iif((day([Date])>=13) and (day([Date])<=15),order,0)) as days13to15,
            sum(iif((day([Date])>=16) and (day([Date])<=18),order,0)) as days16to18,
            sum(iif((day([Date])>=19) and (day([Date])<=21),order,0)) as days19to21,
            sum(iif((day([Date])>=22) and (day([Date])<=24),order,0)) as days22to24,
            sum(iif((day([Date])>=25) and (day([Date])<=27),order,0)) as days25to27,
            sum(iif((day([Date])>=28) and (day([Date])<=31),order,0)) as days28to31
from        tbl
where       [Date] between x and y
group by    year([Date]),
            month([Date])

【讨论】:

  • 我在总结什么?我正在尝试对订单列求和。
  • 不是对列本身求和,而是条件计数(注意末尾的 1 或 0)
  • 如果订单在第 1 天到第 3 天之间,则加 1,否则加 0。总数是每个组的条件计数。
  • 你确实想要计数,对吧?如果您想对订单号本身求和,您可以将函数中的每个 1 替换为“order”。是这样吗?如果是这样,我会更新答案。
  • 对不起,我想要的是订单的总和而不是数量,这是我的错误。
【解决方案2】:

考虑Partition Function 和交叉表,例如:

TRANSFORM Sum(Calendar.Order) AS SumOfOrder
SELECT Month([CalDate]) AS TheMonth, Partition(Day([Caldate]),1,31,3) AS DayGroup
FROM Calendar
GROUP BY Month([CalDate]), Partition(Day([Caldate]),1,31,3)
PIVOT Year([CalDate]);

顺便说一句,我希望您没有将字段/列命名为日期。

【讨论】:

  • 效果很好,分区功能很完美,虽然我不确定为什么需要 Pivot。
  • 我认为交叉表更漂亮:) 你不必拥有它,但它确实可以很好地分组!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多