MySQL (ActiveRecord) Подсчет строк, в которых столбец даты находится в или перед сгруппированным месяцем и годом - PullRequest
1 голос
/ 03 апреля 2019

В настоящее время я рассчитываю пользовательские назначения, созданные в определенный месяц или ранее в отдельных запросах для комбинаций месяц / год за последние 12 месяцев.Однако они оказываются медленнее, чем мне хотелось бы, и я хотел бы посмотреть, есть ли способ объединить все эти запросы в один.

Это выполняется из приложения Ruby on Rails (5.0) через ActiveRecordмодели, подключенные к базе данных MySQL (5.6.10).

Этот запрос ActiveRecord

User.joins(:child_classrooms).where('assignments.created_at <= ?', DateTime.new(month_year[0], month_year[1]).end_of_month).count('DISTINCT users.id')

создает этот запрос mysql

SELECT COUNT(DISTINCT users.id) 
FROM `users` INNER JOIN `assignments` ON `assignments`.`user_id` = `users`.`id` AND `assignments`.`role_id` = 3 AND `assignments`.`assignable_type` = 'Student' 
             INNER JOIN `students` ON `students`.`id` = `assignments`.`assignable_id` 
             INNER JOIN `classrooms_students` ON `classrooms_students`.`student_id` = `students`.`id` 
             INNER JOIN `classrooms` ON `classrooms`.`id` = `classrooms_students`.`classroom_id` 
WHERE (assignments.created_at <= '2019-04-30 23:59:59')

Вышеупомянутый запрос производится двенадцать раз(один раз для каждого из последних двенадцати месяцев, меняя метку времени в предложении where), и вместо этого я хотел бы иметь один запрос, который возвращает те же данные, сгруппированные по году и месяцу, с учетом assignments.created_at <= сгруппированных года и месяца.

Я знаком с тем, как группировать по годам и месяцам, но я запутался в том, как считать только те строки, в которых метка времени, созданная в момент времени, находится перед или после сгруппированных года и месяца.

1 Ответ

0 голосов
/ 03 апреля 2019

Вам нужно будет также выбрать год и месяц, чтобы вы получили по одной строке для каждого из них.Затем вы можете сгруппировать по этим столбцам:

SELECT year(assignments.created_at),month(assignments.created_at),COUNT(DISTINCT users.id) 
FROM `users` INNER JOIN `assignments` ON `assignments`.`user_id` = `users`.`id` AND `assignments`.`role_id` = 3 AND `assignments`.`assignable_type` = 'Student' 
             INNER JOIN `students` ON `students`.`id` = `assignments`.`assignable_id` 
             INNER JOIN `classrooms_students` ON `classrooms_students`.`student_id` = `students`.`id` 
             INNER JOIN `classrooms` ON `classrooms`.`id` = `classrooms_students`.`classroom_id` 
WHERE (assignments.created_at <= '2019-04-30 23:59:59')
GROUP BY year(assignments.created_at),month(assignments.created_at)

РЕДАКТИРОВАТЬ Возможно, вам не нужен пункт WHERE

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...