如何在MySQL Group By查询中查找唯一值?

时间:2018-09-03 10:09:54

标签: mysql

  

MySQL TABLE: numbers

+----+-----+------------+
| ID | NUM |   CREATED  |
+----+-----+------------+
| 1  | 11  | 2018-01-01 |
+----+-----+------------+
| 2  | 22  | 2018-02-01 |
+----+-----+------------+
| 3  | 11  | 2018-03-01 |
+----+-----+------------+
| 4  | 44  | 2018-04-01 |
+----+-----+------------+
| 6  | 44  | 2018-04-02 |
+----+-----+------------+
| 5  | 22  | 2018-05-01 |
+----+-----+------------+

在此表中,ID主键NUM是随机值,而CREATED日期

  

我的查询:

SELECT
  DATE_FORMAT(CREATED,'%Y-%m') AS Month,
  COUNT(NUM) AS TotalNum,
  COUNT(DISTINCT(NUM)) AS UniqueNum
FROM
  `numbers`
GROUP BY
  DATE_FORMAT(CREATED,'%Y-%m')
  

我的查询结果

+---------+----------+-----------+
| Month   | TotalNum | UniqueNum |
+---------+----------+-----------+
| 2018-01 |    1     |     1     |
+---------+----------+-----------+
| 2018-02 |    1     |     1     |
+---------+----------+-----------+
| 2018-03 |    1     |     1     |
+---------+----------+-----------+
| 2018-04 |    2     |     1     |
+---------+----------+-----------+
| 2018-05 |    1     |     1     |
+---------+----------+-----------+
  

但是我的预期结果是:

+---------+----------+-----------+
| Month   | TotalNum | UniqueNum |
+---------+----------+-----------+
| 2018-01 |    1     |     1     |
+---------+----------+-----------+
| 2018-02 |    1     |     1     |
+---------+----------+-----------+
| 2018-03 |    1     |     0     |
+---------+----------+-----------+
| 2018-04 |    2     |     1     |
+---------+----------+-----------+
| 2018-05 |    1     |     0     |
+---------+----------+-----------+

UniqueNum的结果应该是在{strong> 2018-03 月中的0。由于{strong> 2018-01 月中已经存在NUM 11。

UniqueNum的结果应该是 2018-05 月中的0。因为NUM 22在 2018-02 月中已经存在。

我想找到每个月的唯一编号。如何通过更新 MySQL查询来获得预期的结果?请帮忙。

2 个答案:

答案 0 :(得分:3)

您只需要将表与其自身连接,然后仅返回之前创建日期不存在的数字即可。

SELECT
  DATE_FORMAT(n.CREATED,'%Y-%m') AS Month,
  COUNT(n.NUM) AS TotalNum,
  COUNT(un.NUM) AS UniqueNum
FROM
  `numbers` n
LEFT JOIN (SELECT ID, NUM FROM numbers n1 WHERE NOT EXISTS (SELECT 1 FROM numbers n2 WHERE n1.NUM = n2.NUM AND n2.CREATED < n1.CREATED)) un ON n.ID = un.ID 
GROUP BY
  DATE_FORMAT(n.CREATED,'%Y-%m')

答案 1 :(得分:0)

通常适用于我的解决方案是嵌套查询 希望这会有所帮助

SELECT
    Month,
    SUM(NUMCNT) AS TotalNum,
    COUNT(NUM) AS UniqueNum
FROM
    (
SELECT
    DATE_FORMAT(CREATED,'%Y-%m') AS Month,
    NUM,
    COUNT(NUM) AS NUMcnt
FROM
    `numbers`
GROUP BY
    Month,
    NUM
) a
;