【问题标题】:Group by a summed variable按求和变量分组
【发布时间】:2017-02-14 11:52:09
【问题描述】:
SELECT deposit.numberSuccessfulDeposits, count(distinct userid) 
FROM deposit WHERE deposit.asOfDate between '2016-04-01 00:00:00' and '2016-04-03 23:59:59'
AND deposit.licenseeId = 1306
GROUP BY deposit.numberSuccessfulDeposits

样本输出

numberSuccessfulDeposits     count(distinct userid) 
 0   228 
 1   878 
 2   90 
 3   37 
 4   17 

但是,如果 Bob 在周一进行了 1 次存款,在周二进行了 3 次存款,那么成功存款次数将同时计入“1”和“3”。

numberSuccessfulDeposits     count(distinct userid) 
 0   ## 
 1   1 
 2   ## 
 3   1 
 4   ## 

理想情况下,它应该只计入“4”

numberSuccessfulDeposits     count(distinct userid) 
 0   ## 
 1   ## 
 2   ## 
 3   ## 
 4   1

想法?

【问题讨论】:

    标签: mysql group-by sum distinct


    【解决方案1】:

    在子查询中计算每个用户的总和,然后在主查询中计算每个用户的总数。

    SELECT totalDeposits, COUNT(*)
    FROM (SELECT userid, SUM(numberOfSuccessfulDeposits) AS totalDeposits
          FROM deposit 
          WHERE deposit.asOfDate between '2016-04-01 00:00:00' and '2016-04-03 23:59:59'
          AND deposit.licenseeId = 1306
          GROUP BY userid) AS subquery
    GROUP BY totalDeposits
    

    【讨论】:

    • 好的。 Kamil G. 和 Barmar 的建议都奏效了。现在,我如何将超过 3 个存款的所有内容归为 3 个以上的类别?
    【解决方案2】:

    将分组更改为基于用户并汇总所有存款发生。然后为这些存款的每笔总和计算用户数:

    SELECT
      numberSuccessfulDeposits,
      COUNT(userid) AS users_count
    FROM (
      SELECT 
        sum(numberSuccessfulDeposits) AS numberSuccessfulDeposits, 
        userid
      FROM deposit
      WHERE asOfDate between '2016-04-01 00:00:00' and '2016-04-03 23:59:59'
        AND licenseeId = 1306
      GROUP BY userid
      ) t
    GROUP BY numberSuccessfulDeposits
    

    编辑:将存款分为 0、1、2、3+ 类别如下所示:

    SELECT
      numberSuccessfulDeposits,
      COUNT(userid) AS user_count
    FROM (
      SELECT
        CASE WHEN numberSuccessfulDeposits >= 3 THEN '3+' ELSE numberSuccessfulDeposits::TEXT END AS numberSuccessfulDeposits,
        userid
      FROM (
        SELECT 
          sum(numberSuccessfulDeposits) AS numberSuccessfulDeposits, 
          userid
        FROM deposit
        WHERE asOfDate between '2016-04-01 00:00:00' and '2016-04-03 23:59:59'
          AND licenseeId = 1306
        GROUP BY userid
        ) t
      ) f
    GROUP BY numberSuccessfulDeposits
    

    【讨论】:

    • 我不认为DISTINCT 可以与SUM 一起使用,只能与COUNT 一起使用。即使可以,也是不对的。如果 Bob 在周一存入 1 笔存款,在周三存入 1 笔,这只会算作 1 笔存款,而不是 2 笔。
    • 是的,可以和SUM一起使用。为什么不?对于后一部分 - 我忘记了数据列,所以你是对的,我已经删除了它,谢谢。
    • 我以为这是COUNT的一个特殊功能,但我刚刚查看了手册,你是对的——它也适用于AVGMAXMIN等. 我不确定为什么您只想对不同的值进行求和/平均,而对于MAXMIN,我看不出它会有什么不同。跨度>
    • 我也认为没有理由将它用于MAXMIN。我看到AVG 的用途,当您只想将值计入平均值一次以在不同的集合(非规范化数据或类似的东西)中执行平均值时,SUM 可能是:让我们看看收据每个产品只计算一次时花了多少钱,但这涉及CASE声明。
    • 但那是错误的。如果两种不同的产品价格相同怎么办? SUM(DISTINCT price) 只比较价格,而不是产品。这似乎是为了笼统而提出的,但可能没有真正的用处。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-11
    • 2015-07-19
    相关资源
    最近更新 更多