Если есть вероятность, что в таблице ваших действий нет активности в определенный день, то хитрость fa06 не сработает.Простой способ охватить этот случай - добавить несколько нулевых записей до того, как вы внесете сумму:
SELECT DATE(d), SUM(c)
FROM (
SELECT a.end_time as d, a.calories as c
FROM activities a
JOIN user_activities uc ON uc.activity_id = a.id
WHERE uc.user_id = 1
AND DATE(a.end_time) >= CURRENT_DATE - INTERVAL 6 DAY
UNION ALL
SELECT CURRENT_DATE, 0
UNION ALL
SELECT CURRENT_DATE - INTERVAL 1 DAY, 0
UNION ALL
SELECT CURRENT_DATE - INTERVAL 2 DAY, 0
UNION ALL
SELECT CURRENT_DATE - INTERVAL 3 DAY, 0
UNION ALL
SELECT CURRENT_DATE - INTERVAL 4 DAY, 0
UNION ALL
SELECT CURRENT_DATE - INTERVAL 5 DAY, 0
UNION ALL
SELECT CURRENT_DATE - INTERVAL 6 DAY, 0
) z
GROUP BY DATE(d)
Метод fa06 основан на том, что в таблице операций каждый день по одной записи.Это верный способ решения проблемы, но вы не знаете, какие данные содержат эти таблицы (подсказка: при публикации вопроса о БД включайте образцы данных из каждой таблицы)
С помощью этого метода мы делаемнаш поиск как обычно, но мы также генерируем 7 фальшивых строк с датами за последние 7 дней и 0 калорий.При добавлении к реальному количеству калорий они не содержат жира;) и когда нет данных за конкретный день, они автономно предоставляют 0
. Если вы хотите больше дней, рассмотрите возможность перехода к шаблону генерации строк.,В MySQL нет таких генераторов строк, как в других БД, но самый простой способ - создать переменную, инициализировать ее с 0, затем увеличивать и использовать ее для каждой строки, возвращаемой из таблицы, содержащей не менее 30 строк:
SELECT CURRENT_DATE - INTERVAL (@row := @row + 1) DAY as dt, 0 as cal
FROM activities t, (SELECT @row := -1) r
LIMIT 30
Теория, лежащая в основе этого: таблица содержит не менее 30 строк, переменная @row имеет значение -1 и существует для запроса в сеансе.Когда строки извлекаются и возвращаются, @row увеличивается, а затем возвращается (так что это 0, 1, 2 ..), и это увеличивающееся число используется для вычитания 0, 1, 2 и т. Д. Выходных текущих данных, что дает нампоследовательность дат за последние 30 дней
SELECT DATE(d), SUM(c)
FROM (
SELECT a.end_time as d, a.calories as c
FROM activities a
JOIN user_activities uc ON uc.activity_id = a.id
WHERE uc.user_id = 1
AND DATE(a.end_time) >= CURRENT_DATE - INTERVAL 29 DAY
UNION ALL
SELECT CURRENT_DATE - INTERVAL (@row := @row + 1) DAY as dt, 0 as cal
FROM activities t, (SELECT @row := -1) r
WHERE @row < 30
) z
GROUP BY DATE(d)
Обратите внимание, что я не смог протестировать ни один из этих запросов;вторая может иметь небольшую синтаксическую ошибку.Если оказывается, что это не работает, и ошибка является нетривиальной / что-то, что вы не можете исправить, дайте мне знать.
Отладка:
Запустите каждый из этих запросов по отдельности.Я не знаю, сколько строк это будет производить:
SELECT a.end_time as d, a.calories as c
FROM activities a
JOIN user_activities uc ON uc.activity_id = a.id
WHERE uc.user_id = 1
AND DATE(a.end_time) >= CURRENT_DATE - INTERVAL 29 DAY
И этот должен произвести 30 строк.Если этого не произойдет, это будет потому, что вы не использовали таблицу с хотя бы 30 строками:
SELECT CURRENT_DATE - INTERVAL (@row := @row + 1) DAY as dt, 0 as cal
FROM activities t, (SELECT @row := -1) r
LIMIT 30
Редактировать:
Исправлена ошибка с этим - LIMIT применялся послеСоюз;это дало нежелательные результаты