MySQL 条件 SUM 使用 GROUP BY 和 DISTINCT

Posted

技术标签:

【中文标题】MySQL 条件 SUM 使用 GROUP BY 和 DISTINCT【英文标题】:MySQL conditional SUM using GROUP BY and DISTINCT 【发布时间】:2014-01-12 23:34:01 【问题描述】:

我的 foos 表中有以下数据结构:

-----------------------------------------------
| id | bar_id | baz_id | date       | value   |
-----------------------------------------------
| 1  | 1      | 1      | 2013-12-01 | failure |
| 2  | 1      | 1      | 2013-12-09 | failure |
| 3  | 2      | 1      | 2013-12-02 | success |
| 4  | 3      | 1      | 2013-12-10 | success |
| 5  | 3      | 1      | 2013-12-01 | failure |
| 6  | 3      | 1      | 2013-12-08 | success |
| 7  | 1      | 2      | 2013-12-02 | success |
| 8  | 1      | 2      | 2013-12-08 | failure |
| 9  | 1      | 2      | 2013-12-03 | success |
| 10 | 2      | 2      | 2013-12-07 | failure |
| 11 | 2      | 2      | 2013-12-08 | failure |
| 12 | 3      | 2      | 2013-12-04 | success |
| 13 | 3      | 3      | 2013-12-14 | failure |
-----------------------------------------------

我的目标是为不同的 baz_id 获取每个 bar_id 的成功/总数。例如:

------------------------------
| bar_id | successes | total |
------------------------------
| 1      | 1         | 2     |
| 2      | 1         | 2     |
| 3      | 2         | 3     |
------------------------------

这是一个有效的查询:

SELECT foos.bar_id,
    successes,
    COUNT(distinct baz_id) as total
  FROM foos
    LEFT JOIN 
        (SELECT bar_id, count(distinct baz_id) as successes
          FROM foos
          WHERE value = "success"
          GROUP BY bar_id) as other
      ON foos.bar_id = other.bar_id
  GROUP BY bar_id

有没有办法在不进行子选择的情况下使用 MySQL 函数获得成功列?似乎必须有一种方法可以使用 GROUP_CONCAT 或其他 Group By Functions 之一这样做。

编辑

使用SUM(value="success") 很接近,但会为不同的 baz_id 计算所有成功,而不是只计算一次成功:

SELECT bar_id,
    SUM(value="success") AS successes,
    COUNT(distinct baz_id) as total
  FROM foos   
  GROUP BY bar_id

------------------------------
| bar_id | successes | total |
------------------------------
| 1      | 2         | 2     | <- Successes should be 1
| 2      | 1         | 2     |
| 3      | 3         | 3     | <- Successes should be 2
------------------------------

【问题讨论】:

我非常感谢有关如何使这个问题变得更好的反馈,因为它被否决了。 【参考方案1】:

您可以使用CASEDISTINCT 来获得相同的结果;

SELECT bar_id, 
  COUNT(DISTINCT CASE WHEN value='success' THEN baz_id ELSE NULL END) successes, 
  COUNT(DISTINCT baz_id) total
FROM foos
GROUP BY bar_id;

An SQLfiddle to test with.

【讨论】:

优秀。这正是我正在寻找的类型。而且,正如我所希望的那样,与我上面使用的版本相比,这可以节省大量时间(约 40%)的查询时间。

以上是关于MySQL 条件 SUM 使用 GROUP BY 和 DISTINCT的主要内容,如果未能解决你的问题,请参考以下文章

mysql 子查询 group by的使用

mysql:group by,order by

MySQL分组条件,group by order by limit 顺序

【MySQL】分组查询(GROUP BY)

怎么使用group by?

GROUP BY和HAVING 以及mysql中常用的日期函数