@alexfyodrv

Как сделать групировку запроса по месяцу и вложеный подсчет результатов по условию?

Приветствую,
подскажите пожалуйста как можно реализовать групировку кол-ва строк до определенной даты и затем посчитать строки внутри групы по условию?
Например:
Каждый месяц добавляются новые пользователи и мне нужно вывести статистику о них как кол-во пользователей увеличивалось. Мне нужно от текущей даты отнять ровно месяц, сегодня 12 июля, затем 12 июня, 12 мая и т.д и узнать сколько пользователей было на тот момент, далее пользователи имеют группы: user, customer и группа "все".

Сейчас запрос рекурсивно достает пользователей из базы для каждого месяца, далее я сам создаю из этого массив данных. Если это можно реализовать через Eloquent буду благодарен за пример.
select count(*) from `users` where created_at <= `2019-07-12`
select count(*) from `users` where created_at <= `2019-07-12` and type = 'user'
select count(*) from `users` where created_at <= `2019-07-12` and type = 'customer'

select count(*) from `users` where created_at <= `2019-06-12`
select count(*) from `users` where created_at <= `2019-06-12` and type = 'user'
select count(*) from `users` where created_at <= `2019-06-12` and type = 'customer'


$stats[] = [
            '2019-07-12' => [
              'all' => $this->countAll(),
              'users' => $this->countUsers(),
              'customers' => $this->countCustomers(),
            ]
        ];
  • Вопрос задан
  • 125 просмотров
Пригласить эксперта
Ответы на вопрос 4
@miki131
Как вариант чтобы не делать по 3 запроса
select count(*), sum(type = 'user'), sum(type = 'customer') from `users` where created_at <= `2019-07-12`
Ответ написан
BojackHorseman
@BojackHorseman
...в творческом отпуске...
SELECT 
  SUM(CASE WHEN `created_at ` < `2019-06-12` THEN 1 ELSE 0 END) as _m1,
  SUM(CASE WHEN `created_at ` < `2019-07-12` THEN 1 ELSE 0 END) as _m2,
  SUM(CASE WHEN `created_at ` < `2019-07-12` THEN 1 ELSE 0 END) - SUM(CASE WHEN `created_at ` < `2019-06-12` THEN 1 ELSE 0 END)  as _diff
...
Ответ написан
@NubasLol
Можно как-то так.

select
    sum(case when type = "all" then 1 else 0 end) as "all",
from (values ('2019-01-12', '2019-07-12')) AS dates (dateStart, dateEnd)
 inner join users on users.created_at > dates.dateStart::date and users.created_at < dates.dateEnd::date

group by dates.dateStart::date


Но правильно такую групировку длеать уже в php. А в sql
select dates.dateStart::date, type, count(*)
group by dates.dateStart::date
Ответ написан
Для работы с датами я использую Carbon. Загоняют в цикл ( например addMonth или subMonth) и условие и на выходе получаю массив данных с готовыми результатами. Может мой ответ вам слабо поможет, так как не люблю "сырые" запросы
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы