MySQL按月,年计数,如果没有则显示0

时间:2019-12-05 07:55:43

标签: mysql sql

我在下面有两个表格。我从表 job_statuses 中获取所有不同的月份和年份,并将它们分组(在查询的第1部分中完成)。然后,我想浏览这些结果并计算第二张表 ticket_jobs 中的所有行(如果它们在当前的月份和年份间隔中),并且要计算该行,它必须在内包含字符串“ claim” extra_info字段。问题是我还希望在当前时间范围内没有行的结果。我读过解决该问题的解决方案,就是对同一张表使用左连接,但是我不确定我是否正确使用了它,因为它们目前仍未显示在结果中。

查询理论:从 job_statuses 中获取所有不同的月份和年份,循环浏览它们并计算 ticket_jobs 中当前时间段内的行月和年,并且在 extra_info 中具有“声明”。如果在当前时间范围内没有显示,则显示0。

表:job_statuses (数据,使用了哪些资源以及何时使用):

id (int, primary ID)
input
created_at (timestamp ex: 2018-06-05 08:00:00)
finished_at (timestamp ex: 2018-06-06 08:00:00)

表:ticket_jobs (有关所有票证以及已领取票证的数据)

id (int, primary ID)
extra_info (text ex: "claimed:3256262")
created_at (timestamp ex: 2018-06-05 08:00:00)
finished_at (timestamp ex: 2018-06-06 08:00:00)

当前结果:

+------+-------+---------+
| year | month | claimed |
+------+-------+---------+
| 2018 | 6     | 120     |
+------+-------+---------+
| 2018 | 7     | 40      |
+------+-------+---------+
| 2018 | 8     | 125     |
+------+-------+---------+
| 2018 | 11    | 46      |
+------+-------+---------+
| 2018 | 12    | 24      |
+------+-------+---------+
| 2019 | 3     | 29      |
+------+-------+---------+

想要实现

+------+-------+---------+
| year | month | claimed |
+------+-------+---------+
| 2018 | 6     | 120     |
+------+-------+---------+
| 2018 | 7     | 40      |
+------+-------+---------+
| 2018 | 8     | 125     |
+------+-------+---------+
| 2018 | 9     | 0       |
+------+-------+---------+
| 2018 | 10    | 0       |
+------+-------+---------+
| 2018 | 11    | 46      |
+------+-------+---------+
| 2018 | 12    | 24      |
+------+-------+---------+
| 2019 | 1     | 0       |
+------+-------+---------+

当前查询

SELECT year, month, claimed
    FROM 
    (
        //  Get all months & years from job_statuses table

        (SELECT YEAR(created_at) AS year, MONTH(created_at) AS month FROM job_statuses 
         GROUP BY YEAR(created_at), MONTH(created_at)) x, 

        //  Count rows in ticket_jobs table for each year&month result from above that contains "like", 
        //  or put 0 if count returns empty rows

        (SELECT YEAR(t.created_at) y, MONTH(t.created_at) m, COUNT(*) AS claimed 
        FROM ticket_jobs t
        LEFT JOIN ticket_jobs lj ON t.created_at = lj.created_at AND 
        lj.extra_info LIKE "%claim%" 
        GROUP BY YEAR(t.created_at), MONTH(t.created_at)) b
    )

WHERE year=b.y AND month=b.m 
GROUP BY year, month
ORDER BY year ASC, month ASC

示例

执行完第一部分后,我们从 job_statuses 表中获得此示例数据

+------+-------+
| year | month |
+------+-------+
| 2018 | 7     |
+------+-------+
| 2018 | 8     |
+------+-------+
| 2018 | 9     |
+------+-------+

我们的 ticket_jobs 表中有示例数据

+----+----------------+---------------------+---------------------+
| id | extra_info     | created_at          | finished_at         |
+----+----------------+---------------------+---------------------+
| 1  | {"claimed":125} | 2018-07-05 06:33:50 | 2018-07-05 06:42:50 |
+----+----------------+---------------------+---------------------+
| 2  | {"claimed":86}  | 2018-08-15 06:33:50 | 2018-08-22 06:33:50 |
+----+----------------+---------------------+---------------------+
| 3  |                | 2018-09-01 06:33:50 | 2018-09-03 06:33:50 |
+----+----------------+---------------------+---------------------+

因此结果将是

+------+-------+---------+
| year | month | claimed |
+------+-------+---------+
| 2018 | 7     | 1       |
+------+-------+---------+
| 2018 | 8     | 1       |
+------+-------+---------+
| 2018 | 9     | 0       |
+------+-------+---------+

1 个答案:

答案 0 :(得分:2)

将以下部分更改为

SELECT YEAR(t.created_at) y, MONTH(t.created_at) m, COUNT(extra_info) AS claimed 
FROM ticket_jobs t
LEFT OUTER JOIN ticket_jobs lj ON t.created_at = lj.created_at AND  lj.extra_info LIKE "%claim%" 
GROUP BY YEAR(t.created_at), MONTH(t.created_at)

SELECT y,m,IFNULL(b.claimed,0) claimed FROM
(
    SELECT YEAR(t.created_at) y, MONTH(t.created_at) m, COUNT(*) AS claimed 
    FROM ticket_jobs t
    LEFT OUTER JOIN ticket_jobs lj ON t.created_at = lj.created_at AND lj.extra_info LIKE "%claim%" 
    GROUP BY YEAR(t.created_at), MONTH(t.created_at)
) b