хотя у вас есть отмеченное решение, у меня есть другой, который, вероятно, упрощающие запрос еще дальше, используя переменные MySQL, так что вы не» t должны ошибочно вводить/вычислять даты и т. д.
Вместо того, чтобы объявлять переменные впереди, вы можете сделать их inline как оператор select, а затем использовать их так, как если бы они были столбцами в другой таблице. Поскольку он создается как одна строка, нет декартова результата. Сначала запрос, тогда я опишу вычисления на нем.
select
sum(if(t.date >= @today AND t.date < @tomorrow, 1, 0)) as TodayCnt,
sum(if(t.date >= @today AND t.date < @tomorrow, amount, 0)) as TodayAmt,
sum(if(t.date >= @yesterday AND t.date < @today, 1, 0)) as YesterdayCnt,
sum(if(t.date >= @yesterday AND t.date < @today, amount, 0)) as YesterdayAmt,
sum(if(t.date >= @FirstOfWeek AND t.date < @EndOfWeek, 1, 0)) as WeekCnt,
sum(if(t.date >= @FirstOfWeek AND t.date < @EndOfWeek, amount, 0)) as WeekAmt
from
transations t,
(select @today := curdate(),
@yesterday := date_add(@today, interval -1 day),
@tomorrow := date_add(@today, interval 1 day),
@FirstOfWeek := date_add(@today, interval +1 - dayofweek(@today) day),
@EndOfWeek := date_add(@FirstOfWeek, interval 7 day),
@minDate := least(@yesterday, @FirstOfWeek)) sqlvars
where
t.date >= @minDate
AND t.date < @EndOfWeek
Теперь даты. Поскольку @variables готовятся последовательно, вы можете подумать об этом как о встроенной программе для установки переменных. Поскольку они являются предварительным запросом, они выполняются сначала и доступны для остальной части запроса, как указано ранее. Поэтому, чтобы начать, я работаю над тем, что «curdate()» - это то, что получает часть даты только без учета времени. Из этого вычтите 1 день (добавьте -1), чтобы получить начало вчера. Добавьте 1 день, чтобы получить Завтра. Затем первая неделя - это текущая дата +1 - фактический день недели (вы скоро увидите). Добавьте 7 дней с первой недели, чтобы получить окончание недели. Наконец, получите, какая бы ни была дата: МЕНЬШЕ между вчерашним днем (который МОЖЕТ существовать в конце предыдущей недели), ИЛИ в начале недели.
Now look at today for example... Feb 23rd.
Sun Mon Tue Wed Thu Fri Sat Sun
21 22 23 24 25 26 27 28
Today = 23
Yesterday = 22
Tomorrow = 24
First of week = 23 + 1 = 24 - 3rd day of week = 21st
End of Week = 21st + 7 days = 28th.
Почему я занимаюсь отключением дат зачистки? Чтобы упростить условие SUM() для> = И <. Если я заявлял, что дата = сегодня, что делать, если ваши транзакции были отмечены по времени. Затем вам нужно будет извлечь часть даты только для квалификации. При таком подходе я могу сказать, что «Сегодня» подсчет и сумма - любая дата> = 23 февраля в 12:00 ночи и < 24 февраля 12:00 полночь. Это все время включительно с 23 февраля до 11:59:59, поэтому МЕНЬШЕ, чем 24 февраля (завтра).
Подобное соображение за вчерашний день включает все, что включено, но не включает в себя все, что «сегодня». Аналогично для недельного диапазона.
Наконец, предложение WHERE ищет самую раннюю дату в качестве диапазона, поэтому ей не нужно пробегать всю базу данных транзакций до конца.
И наконец, если вы когда-нибудь хотели отсчеты и итоги для предыдущей недели/периода, что угодно, вы можете просто экстраполировать и изменить
@today := '2015-01-24'
и вычисления будет, как если запрос был запущен в тот же день ,
Аналогично, если вы решили изменить такой, как в течение месяца, вы можете вычислить первый месяц в первый месяц следующего месяца для итогов MONTHLY.
Надеюсь, вам понравится это гибкое решение для вас.
не использовать между диапазонами дат, решение от DRapp делает это правильно (через> = then <) –