MySQL диапазон дат, если данные недоступны, отображают 0 - PullRequest
1 голос
/ 10 января 2020

У меня есть таблица, здесь приведена структура: 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, 05 , 06 , 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       |

Ответы [ 2 ]

1 голос
/ 10 января 2020

Осталось объединить этот запрос за весь месяц с исходным запросом (смените на подзапрос), например:

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;

Редактировать:

Если вы хотите указать до какой даты, вы можете добавить предложение WHERE во внешний запрос и удалить BETWEEN во втором подзапросе (ваш исходный запрос) следующим образом:

#add WHERE clause here
WHERE XX.dm BETWEEN 2020-01-02' AND '2020-01-07' 

Редактировать 2: только вышеупомянутый запрос генерировать даты в текущем месяце, которому вы его назначаете. Если вы хотите иметь перекрывающиеся даты, я предлагаю вам создать таблицу календаря. Ниже приводится пример из ссылки: { ссылка } (который генерирует 10 000 строк обратных дат из интервала CURDATE().). Здесь я использую тот же запрос, чтобы сгенерировать 20 000 комбинаций дней с текущей датой в качестве центра.

CREATE TABLE calendar (
dates DATE);

INSERT INTO calendar
SELECT dm 
FROM (
    SELECT CURDATE() - INTERVAL (a.a + (10 * b.a) + (100 * c.a) + (1000 * d.a) ) DAY AS dm FROM 
    (SELECT 0 AS a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL 
     SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS a
    CROSS JOIN 
    (SELECT 0 AS a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL 
     SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS b
    CROSS JOIN 
    (SELECT 0 AS a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL 
     SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS c
    CROSS JOIN 
    (SELECT 0 AS a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL 
     SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS d
) a UNION ALL
SELECT dm 
FROM (
    SELECT CURDATE() + INTERVAL (a.a + (10 * b.a) + (100 * c.a) + (1000 * d.a) ) DAY AS dm FROM 
    (SELECT 0 AS a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL 
     SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS a
    CROSS JOIN 
    (SELECT 0 AS a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL 
     SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS b
    CROSS JOIN 
    (SELECT 0 AS a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL 
     SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS c
    CROSS JOIN 
    (SELECT 0 AS a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL 
     SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS d
) a;

Приведенный выше запрос будет вставлен в таблицу calendar с диапазоном дат от 1992-08-28 до 2047-05-30. Тогда вам нужно всего лишь LEFT JOIN таблицу calendar с остальным кодом, как показано ниже:

SELECT XX.dates AS 'Tanggal',IFNULL(YY.jumlah,0) AS 'Jumlah' 
FROM calendar XX
LEFT JOIN
(SELECT COUNT(id) AS jumlah,tanggal 
FROM tb_trafik_berita 
GROUP BY tanggal) YY 
ON XX.dates =DATE(YY.tanggal)
WHERE XX.dates BETWEEN '2019-12-13' AND '2020-01-07' 
ORDER BY XX.dates ;
1 голос
/ 10 января 2020

Мы можем попробовать ввести отсутствующие даты через объединение с календарной таблицей:

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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...