Я не фанат других ответов, требующих создания таблиц и тому подобное. Этот запрос делает это эффективно без вспомогательных таблиц.
SELECT
IF(score IS NULL, 0, score) AS score,
b.Days AS date
FROM
(SELECT a.Days
FROM (
SELECT curdate() - INTERVAL (a.a + (10 * b.a) + (100 * c.a)) DAY AS Days
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
) a
WHERE a.Days >= curdate() - INTERVAL 30 DAY) b
LEFT JOIN your_table
ON date = b.Days
ORDER BY b.Days;
Итак, давайте рассмотрим это.
SELECT
IF(score IS NULL, 0, score) AS score,
b.Days AS date
If обнаружит дни, в которых не было оценок, и установит их на 0. b.Days - это настроенное количество дней, которое вы выбрали для получения текущей даты, до 1000.
(SELECT a.Days
FROM (
SELECT curdate() - INTERVAL (a.a + (10 * b.a) + (100 * c.a)) DAY AS Days
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
) a
WHERE a.Days >= curdate() - INTERVAL 30 DAY) b
Этот подзапрос я видел в stackoverflow. Он эффективно генерирует список за последние 1000 дней с текущей даты. Интервал (в настоящее время 30) в предложении WHERE в конце определяет, какие дни будут возвращены; максимальное значение равно 1000. Этот запрос можно легко изменить, чтобы он возвращал даты за 100 лет, но для большинства вещей 1000 должен подходить.
LEFT JOIN your_table
ON date = b.Days
ORDER BY b.Days;
Это та часть, которая переносит вашу таблицу, в которой содержится оценка. Вы сравниваете с выбранным диапазоном дат из запроса генератора данных, чтобы иметь возможность заполнять нулями там, где это необходимо (оценка будет изначально установлена на NULL
, потому что это LEFT JOIN
; это исправлено в операторе выбора). Я также заказываю это по датам, просто потому что. Это предпочтение, вы также можете заказать по счету.
До ORDER BY
вы могли легко присоединиться к вашей таблице с информацией о пользователе, которую вы упомянули при редактировании, чтобы добавить это последнее требование.
Надеюсь, эта версия запроса кому-нибудь поможет. Спасибо за чтение.