Ответ 1
Я думаю, что наличие таблицы календаря - хорошая идея; вы можете получить много функций отчетности и запросов, особенно при заполнении разреженных диапазонов данных.
Я нашел эту статью с тем, что кажется хорошим примером.
Каков наилучший способ в mysql генерировать ряд дат в заданном диапазоне?
Приложение, которое я имею в виду, это написать запрос отчета, который возвращает строку для каждой даты, независимо от того, есть ли какие-либо данные для отчета. В простейшей форме:
select dates.date, sum(sales.amount)
from <series of dates between X and Y> dates
left join sales on date(sales.created) = dates.date
group by 1
Я попытался создать таблицу с большим количеством дат, но это кажется плохим обходным решением.
Я думаю, что наличие таблицы календаря - хорошая идея; вы можете получить много функций отчетности и запросов, особенно при заполнении разреженных диапазонов данных.
Я нашел эту статью с тем, что кажется хорошим примером.
если вы находитесь в такой ситуации, как я, где создание временных таблиц запрещено, а переменные параметра также не разрешены, но вы хотите создать список дат в конкретный период, скажем, в текущем году сделать некоторую агрегацию, используйте этот
select * from
(select adddate('1970-01-01',t4*10000 + t3*1000 + t2*100 + t1*10 + t0) gen_date from
(select 0 t0 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) t0,
(select 0 t1 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) t1,
(select 0 t2 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) t2,
(select 0 t3 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) t3,
(select 0 t4 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) t4) v
where gen_date between '2017-01-01' and '2017-12-31'
Вы можете использовать серию дат переменной:
Set @i:=0;
SELECT DATE(DATE_ADD(X,
INTERVAL @i:[email protected]+1 DAY) ) AS datesSeries
FROM yourtable, (SELECT @i:=0) r
where @i < DATEDIFF(now(), date Y)
;
Не уверен, что это то, что вы пробовали:).
Следующее использование выше сгенерированного запроса в виде таблицы в left join
:
set @i:=0;
select
d.dates,
sum(s.amount) as TotalAmount
from(
SELECT DATE(DATE_ADD(X,
INTERVAL @i:[email protected]+1 DAY) ) AS dateSeries
FROM Sales, (SELECT @i:=0) r
where @i < DATEDIFF(now(), date Y)
) dates d
left join Sales s
on Date(s.Created) = Date(d.dateSeries)
group by 1
;
Вы также можете использовать временную таблицу для создания серии дат. Проверьте ниже запрос:
CREATE TEMPORARY TABLE daterange (dte DATE);
SET @counter := -1;
WHILE (@counter < DATEDIFF(DATE(_todate), DATE(_fromdate))) DO
INSERT daterange VALUES (DATE_ADD(_fromdate, INTERVAL @counter:[email protected] + 1 DAY));
END WHILE;
SELECT dates.dte, SUM(sales.amount)
FROM daterange dates
LEFT JOIN sales ON DATE(sales.created) = dates.date
GROUP BY dates.dte;