MySQL日期范围,如果数据不可用,则显示0

问题描述 投票:1回答:2

我这里有一张桌子,这里是结构:id,id_berita,ip_user,tanggal

我尝试使用此查询:

select count(id) as jumlah,tanggal from tb_trafik_berita WHERE (tanggal BETWEEN '2020-01-02 00:00:00' AND '2020-01-07 23:59:00') group by tanggal

以及该查询的输出,例如:

tanggal             | jumlah  |
____________________|_________|
2020-01-02 04:13:25 | 1       |
2020-01-02 04:13:39 | 1       |     
2020-01-02 05:02:44 | 1       |
2020-01-03 13:23:22 | 1       |
2020-01-03 13:29:20 | 1       |
2020-01-04 01:36:45 | 1       |
2020-01-04 01:41:30 | 1       |
2020-01-07 14:37:08 | 1       |
2020-01-07 15:05:21 | 1       |

输出仅显示表上可用的数据(仅这些日期:02,03,04,07)

如果我希望输出还显示表上不可用的日期:02,03,04,0506,07,但将值设置为0,

所以预期的输出是:

tanggal             | jumlah  |
____________________|_________|
2020-01-02 04:13:25 | 1       |
2020-01-02 04:13:39 | 1       |     
2020-01-02 05:02:44 | 1       |
2020-01-03 13:23:22 | 1       |
2020-01-03 13:29:20 | 1       |
2020-01-04 01:36:45 | 1       |
2020-01-04 01:41:30 | 1       |
2020-01-05 00:00:00 | 0       | <<< set 0 cuz data on table not available
2020-01-06 00:00:00 | 0       | <<< set 0 cuz data on table not available
2020-01-07 14:37:08 | 1       |
2020-01-07 15:05:21 | 1       |
mysql database
2个回答
1
投票

我们可以尝试通过带有日历表的联合引入缺少的日期:

SELECT tanggal, COUNT(id) AS jumlah
FROM tb_trafik_berita
WHERE tanggal BETWEEN '2020-01-02 00:00:00' AND '2020-01-07 23:59:00'
GROUP BY tanggal
UNION ALL
SELECT dates.tanggal, 0
FROM
(
    SELECT '2020-01-02' AS tanggal UNION ALL
    SELECT '2020-01-03' UNION ALL
    SELECT '2020-01-04' UNION ALL
    SELECT '2020-01-05' UNION ALL
    SELECT '2020-01-06' UNION ALL
    SELECT '2020-01-07'
) AS dates
LEFT JOIN tb_trafik_berita ttb
    ON dates.tanggal = DATE(ttb.tanggal)
WHERE ttb.tanggal IS NULL
ORDER BY
    tanggal;

0
投票

此查询生成整个当月日期:

SELECT dm FROM
(SELECT CONCAT_WS('-',df,CONCAT(b,c)) dm FROM 
(SELECT DATE_FORMAT(CURDATE(), '%Y-%m') df) a, 
(SELECT 0 b UNION SELECT 1 b UNION SELECT 2 UNION SELECT 3) b,
(SELECT 0 c UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION
SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION
SELECT 9) c) d WHERE DAY(dm) BETWEEN 1 AND DAY(LAST_DAY(dm));

将其与您的原始查询(更改为子查询)像这样:

SELECT XX.dm AS 'Tanggal',IFNULL(YY.jumlah,0) AS 'Jumlah' FROM
(SELECT dm FROM
(SELECT CONCAT_WS('-',df,CONCAT(b,c)) dm FROM 
(SELECT DATE_FORMAT(CURDATE(), '%Y-%m') df) a, 
(SELECT 0 b UNION SELECT 1 b UNION SELECT 2 UNION SELECT 3) b,
(SELECT 0 c UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION
SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION
SELECT 9) c ) d WHERE DAY(dm) BETWEEN 1 AND DAY(LAST_DAY(dm))) XX
LEFT JOIN
(SELECT COUNT(id) AS jumlah,tanggal 
FROM tb_trafik_berita 
WHERE (tanggal BETWEEN '2020-01-02 00:00:00' AND '2020-01-07 23:59:00') 
GROUP BY tanggal) YY 
ON XX.dm=DATE(YY.tanggal)
ORDER BY XX.dm;

如果您想更改月份,只需更改此部分:

DATE_FORMAT(CURDATE(), '%Y-%m') = current year-month (2020-01)
to
DATE_FORMAT(CURDATE() - INTERVAL 1 MONTH , '%Y-%m') = previous year-month (2019-12)
or
DATE_FORMAT(CURDATE() + INTERVAL 1 MONTH , '%Y-%m') = next year-month (2020-02)

您明白了。

编辑:

如果要指定到哪个日期,可以在外部查询中添加WHERE子句,然后可以在第二个子查询(原始查询)中删除BETWEEN,如下所示:

SELECT XX.dm AS 'Tanggal',IFNULL(YY.jumlah,0) AS 'Jumlah' FROM
(SELECT dm FROM
(SELECT CONCAT_WS('-',df,CONCAT(b,c)) dm FROM 
(SELECT DATE_FORMAT(CURDATE(), '%Y-%m') df) a, 
(SELECT 0 b UNION SELECT 1 b UNION SELECT 2 UNION SELECT 3) b,
(SELECT 0 c UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION
SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION
SELECT 9) c ) d WHERE DAY(dm) BETWEEN 1 AND DAY(LAST_DAY(dm))) XX
LEFT JOIN
(SELECT COUNT(id) AS jumlah,tanggal 
FROM tb_trafik_berita 
GROUP BY tanggal) YY 
ON XX.dm=DATE(YY.tanggal)
#add WHERE clause here
WHERE XX.dm BETWEEN 2020-01-02' AND '2020-01-07' 
ORDER BY XX.dm;
© www.soinside.com 2019 - 2024. All rights reserved.