整个数据集的不同计数,按月分组
Posted
技术标签:
【中文标题】整个数据集的不同计数,按月分组【英文标题】:Distinct count for entire dataset, grouped by month 【发布时间】:2018-12-19 20:18:26 【问题描述】:我正在处理一个大致如下所示的销售订单表 (ORDER)(2018 年 12 月 20 日更新以更接近我的实际数据集):
SOID SOLINEID INVOICEDATE SALESAMOUNT AC
5 1 2018-11-30 100.00 01
5 2 2018-12-05 50.00 02
4 1 2018-12-12 25.00 17
3 1 2017-12-31 75.00 03
3 2 2018-01-03 25.00 05
2 1 2017-11-25 100.00 17
2 2 2017-11-27 35.00 03
1 1 2017-11-20 15.00 08
1 2 2018-03-15 30.00 17
1 3 2018-04-03 200.00 05
我可以按 SOID 和 SOLINEID 计算平均销售额:
SELECT SUM(SALESAMOUNT) / COUNT(DISTINCT SOID) AS 'Total Sales per Order ($)',
SUM(SALESAMOUNT) / COUNT(SOLINEID) AS 'Total Sales per Line ($)'
FROM ORDER
这似乎提供了一个非常好的答案,但我得到了一个额外的限制,即这个计数是按年和月计算的。我以为我可以简单地添加
GROUP BY YEAR(INVOICEDATE), MONTH(MONTH)
但这会聚合 SOID,然后执行 COUNT(DISTINCT SOID)。这成为跨越多个月出现的 SOID 的问题,这很常见,因为我们在发货时开具发票。
我想得到这样的东西:
Year Month Total Sales Per Order Total Sales Per Line
2018 11 0.00
最痛心的一点是,如果 SOID 跨越多个,我需要某种方式来定义 SOID 将在哪个月份和年份聚合;为此,我会使用 MAX(INVOICEDATE)。
但是,我只是不确定如何解决这个问题。和?子查询?还有什么?我将不胜感激任何帮助,即使它只是指向正确的方向。
【问题讨论】:
【参考方案1】:您应该为调用和分组选择 Year() 和 month()
SELECT YEAR(INVOICEDATE) year
, MONTH(INVOICEDATE) month
, SUM(SALESAMOUNT) / COUNT(DISTINCT SOID) AS 'Total Sales per Order ($)'
, SUM(SALESAMOUNT) / COUNT(SOLINEID) AS 'Total Sales per Line ($)'
FROM ORDER
GROUP BY YEAR(INVOICEDATE), MONTH(INVOICEDATE)
【讨论】:
此查询将重复计算具有跨越多个月/年的 INVOICEDATE 的 SOID,如在我的示例数据集中。我只希望在最后一个 INVOICEDATE 的月份和年份中计算每个 SOID。【参考方案2】:这是结果,但数据样本没有 enuf 行来显示月份...
SELECT
mDateYYYY,
mDateMM,
SUM(SALESAMOUNT) / COUNT(DISTINCT t1.SOID) AS 'Total Sales per Order ($)',
SUM(SALESAMOUNT) / COUNT(SOLINEID) AS 'Total Sales per Line ($)'
FROM DCORDER as t1
left join
(Select
SOID
,Year(max(INVOICEDATE)) as mDateYYYY
,Month(max(INVOICEDATE)) as mDateMM
From DCOrder
Group By SOID
) as t2
On t1.SOID = t2.SOID
Group by mDateYYYY, mDateMM
mDateYYYY mDateMM Total Sales per Order ($) Total Sales per Line ($)
2018 12 87.50 58.33
我使用了新的 SQL 仍然是 MAX(INVOICEDATE)(not above),新的 12/20 数据,并排除了 AC=17。
YYYY MM Total Sales per Order ($) Total Sales per Line ($)
2017 11 35.00 35.00
2018 1 100.00 50.00
2018 4 215.00 107.50
2018 12 150.00 75.00
【讨论】:
当我没有任何限制时,这个查询似乎给了我正确的数字。不幸的是,我简化了我的问题,它确实有两个额外的约束。基本上,我想排除一个会计代码 AC,如果它是 17,我只想看看 2017 和 2018。当我之前尝试添加这个 WHERE 子句时“外部”分组依据,记录总数与未分组查询的总数不对应。当我在子查询中尝试这个时,我的号码仍然关闭。 在 INVOICEDATE 2017/2018 还是在 max(INVOICEDATE) 2017/2018 ?除了这个和AC = 17,以上是否解决了原来的问题?如果是这样,请单击上面的复选标记。此外,我们需要更多的测试数据来证明这一点。方便我们。 我更新了我的示例以更好地反映我的数据。这些订单跨越数月和数年,我在 AC 列中添加了几个 17。 在 INVOICEDATE 2017/2018 或 max(INVOICEDATE) 2017/2018 时仍需要过滤器的答案和数据 ??那么 2016/2017/2018 年我们会砍掉 2016 年的数据但包括其余的数据吗? 2017/2018/2019 怎么样,最大是 2019 年,我们会放弃整个 SOID 吗? (n.b. 额外的数据看起来不错,AC 有 17 改变了结果......更多稍后) 我开始看到这个问题。 SUM(SALESAMOUNT) “应该”按日历年,所以我们将按 INVOICEDATE 分组。当我们计算 SOID 时,我一直要求将这些汇总到 MAX(INVOICEDATE)。我们不能同时拥有两者!假设我想按 INVOICEDATE 保留 SUM(SALESAMOUNT);有没有一种干净的方法来确保我们只计算每个 SOID 一次?以上是关于整个数据集的不同计数,按月分组的主要内容,如果未能解决你的问题,请参考以下文章