Я хочу получить все данные за последние 10 дней, но когда я добавляю "where", это не работает, как ожидалось.
моя структура таблицы:
CREATE TABLE 'vip' (
'id' int(11) NOT NULL auto_increment,
'cancel_at_period_end' datetime NULL,
'creation_date' datetime default NULL,
'answer' varchar(5) collate utf8_unicode_ci default NULL,
PRIMARY KEY ('id')
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=499 ;
я использовал запрос как:
SELECT days.day, count(users_vip.id) count
FROM (SELECT curdate() as day
union select curdate() - interval 1 day
union select curdate() - interval 2 day
union select curdate() - interval 3 day
union select curdate() - interval 4 day
union select curdate() - interval 5 day
union select curdate() - interval 6 day
union select curdate() - interval 7 day
union select curdate() - interval 8 day
union select curdate() - interval 9 day) days
LEFT JOIN users_vip on days.day = CONVERT(users_vip.creation_date, date)
WHERE users_vip.current_period_end_date >= NOW()
GROUP BY days.day
выход:
date count
2018-08-15 1
Результат, который я хочу, должен быть таким:
date count
2018-08-08 0
2018-08-09 0
2018-08-10 0
2018-08-11 0
2018-08-12 0
2018-08-13 0
2018-08-14 0
2018-08-15 1
2018-08-16 0
2018-08-17 0
ОБНОВИТЬ:
SELECT days.day, count(users_vip.id) count
FROM (SELECT curdate() as day
union select curdate() - interval 1 day
union select curdate() - interval 2 day
union select curdate() - interval 3 day
union select curdate() - interval 4 day
union select curdate() - interval 5 day
union select curdate() - interval 6 day
union select curdate() - interval 7 day
union select curdate() - interval 8 day
union select curdate() - interval 9 day) days
LEFT JOIN users_vip on days.day = CONVERT(users_vip.creation_date, date) AND users_vip.current_period_end_date >= NOW()
GROUP BY days.day
Мы можем изменить WHERE
на AND
и перенести предикат из WHERE
предложение ON
.
Я бы также избегал обертки функций вокруг creation_date
, чтобы использовать индекс. Я бы переписал это условие соответствия.
Я бы сделал что-то вроде этого:
SELECT days.day
, COUNT(users_vip.id) AS count
FROM ( SELECT CURDATE() AS day
UNION ALL SELECT CURATE() + INTERVAL -1 DAY
UNION ALL SELECT CURATE() + INTERVAL -2 DAY
UNION ALL SELECT CURATE() + INTERVAL -3 DAY
UNION ALL SELECT CURATE() + INTERVAL -4 DAY
UNION ALL SELECT CURATE() + INTERVAL -5 DAY
UNION ALL SELECT CURATE() + INTERVAL -6 DAY
UNION ALL SELECT CURATE() + INTERVAL -7 DAY
UNION ALL SELECT CURATE() + INTERVAL -8 DAY
UNION ALL SELECT CURATE() + INTERVAL -9 DAY
) days
LEFT
JOIN users_vip
ON users_vip.creation_date >= days.day
AND users_vip.creation_date < days.day + INTERVAL 1 DAY
AND users_vip.current_period_end_date >= NOW()
GROUP
BY days.day
Я думаю, что вы должны оставить свою таблицу календаря в подзапросе, который объединяет подсчеты в день:
SELECT
days.day AS date,
COALESCE(t.cnt, 0) AS count
FROM
(
SELECT CURDATE() AS day UNION
SELECT CURDATE() - INTERVAL 1 day UNION
SELECT CURDATE() - INTERVAL 2 day UNION
SELECT CURDATE() - INTERVAL 3 day UNION
SELECT CURDATE() - INTERVAL 4 day UNION
SELECT CURDATE() - INTERVAL 5 day UNION
SELECT CURDATE() - INTERVAL 6 day UNION
SELECT CURDATE() - INTERVAL 7 day UNION
SELECT CURDATE() - INTERVAL 8 day UNION
SELECT CURDATE() - INTERVAL 9 day
) days
LEFT JOIN
(
SELECT DATE(creation_date) AS date, COUNT(*) AS cnt
FROM users_vip
WHERE current_period_end_date >= NOW()
GROUP BY DATE(creation_date)
) t
ON days.day = t.date;