Как оптимизировать SQL-запрос с множеством одинаковых вариантов выбора?

Я создал этот запрос, но думаю, что его можно сильно оптимизировать ... но я не знаю, как?

Это запрос, который выбирает незавершенные задачи, которые есть у студента, а также выбирает количество запланированных задач и количество задач, для которых он запросил помощь.

Позже мне нужен не счет, а полная строка ответа, для которого он / она просил помощи, но сейчас я начал с подсчета, так как это казалось проще.

Есть ли кто-нибудь, кто может объяснить мне, как это оптимизировать, или где я могу этому научиться?

SELECT
    gu.user_id,
    notComplete.count AS notComplete,
    planned.count AS planned,
    helpNeeded.need AS helpNeeded
FROM
    `groups_users` gu
LEFT JOIN(
    SELECT
        a.created_by AS user_id,
        COUNT(1) AS 'count'
    FROM
        `answers` a
    WHERE
        a.deleted_at IS NULL AND a.completed_at IS NULL AND a.checked_at IS NULL
    GROUP BY
        a.created_by
) AS notComplete
ON
    notComplete.user_id = gu.user_id
LEFT JOIN(
    SELECT
        a.created_by AS user_id,
        COUNT(1) AS 'count'
    FROM
        `answers` a
    WHERE
        a.deleted_at IS NULL
    GROUP BY
        a.created_by
) AS planned
ON
    planned.user_id = gu.user_id
LEFT JOIN(
    SELECT
        a.created_by AS user_id,
        COUNT(1) AS need
    FROM
        `answers` a
    WHERE
        a.deleted_at IS NULL AND a.requested_help_at IS NOT NULL
    GROUP BY
        a.created_by
) AS helpNeeded
ON
    helpNeeded.user_id = gu.user_id
INNER JOIN `users` u ON
    u.id = gu.user_id AND u.type = 'student'
WHERE
    gu.group_id = 213

Поиск условной агрегации. И вы можете улучшить свой вопрос, добавив образцы данных и ожидаемый результат в виде текста или sqlfiddle.

P.Salmon 13.04.2018 11:01
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
0
1
41
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Попробуйте следующее

SELECT
  gu.user_id,
  SUM(IF(a.deleted_at IS NULL AND a.completed_at IS NULL AND a.checked_at IS NULL,1,0)) AS notComplete,
  SUM(IF(a.deleted_at IS NULL,1,0)) AS planned,
  SUM(IF(a.deleted_at IS NULL AND a.requested_help_at IS NOT NULL,1,0)) AS helpNeeded
FROM `groups_users` gu
JOIN `users` u ON u.id = gu.user_id
LEFT JOIN `answers` a ON a.created_by = gu.user_id
WHERE gu.group_id = 213
  AND u.type = 'student'
GROUP BY gu.user_id

Для второго вопроса попробуйте следующее

SELECT
  gu.user_id,
  IF(a.deleted_at IS NULL AND a.completed_at IS NULL AND a.checked_at IS NULL,1,0) AS notComplete,
  IF(a.deleted_at IS NULL,1,0) AS planned,
  IF(a.deleted_at IS NULL AND a.requested_help_at IS NOT NULL,1,0) AS helpNeeded,
  a.* -- full answer row
FROM `groups_users` gu
JOIN `users` u ON u.id = gu.user_id
LEFT JOIN `answers` a ON a.created_by = gu.user_id
LEFT JOIN `answer_plannedday` ap ON ap.answer_id = a.id
LEFT JOIN `plannedday` p ON p.id = ap.planned_day_id
WHERE gu.group_id = 213
  AND u.type = 'student'  
  AND STR_TO_DATE(CONCAT(p.year, '-', p.month, '-', p.day), '%Y-%m-%d') BETWEEN STR_TO_DATE('2016-12-01', '%Y-%m-%d') AND STR_TO_DATE('2018-04-13', '%Y-%m-%d')

Если вы хотите получить подробную информацию только для notComplete, вы можете поместить все необходимые условия в WHERE

SELECT
  gu.user_id,
  a.* -- full answer row
FROM `groups_users` gu
JOIN `users` u ON u.id = gu.user_id
LEFT JOIN `answers` a ON a.created_by = gu.user_id
LEFT JOIN `answer_plannedday` ap ON ap.answer_id = a.id
LEFT JOIN `plannedday` p ON p.id = ap.planned_day_id
WHERE gu.group_id = 213
  AND u.type = 'student'  
  AND STR_TO_DATE(CONCAT(p.year, '-', p.month, '-', p.day), '%Y-%m-%d') BETWEEN STR_TO_DATE('2016-12-01', '%Y-%m-%d') AND STR_TO_DATE('2018-04-13', '%Y-%m-%d')
  -- you say here that you want to get only these rows
  AND a.deleted_at IS NULL AND a.completed_at IS NULL AND a.checked_at IS NULL

Спасибо!!! Тогда еще кое-что, что, если я хочу фильтровать даты? Макет базы данных дерьмовый, поэтому я должен сделать это, чтобы получить данные, когда задача запланирована: hastebin.com/jizecoqevu.sql Дело в том, что мне нужны полные строки для request_help_at, так что должно быть какое-то соединение, верно? (тогда у меня есть еще два других запроса, которые нужно объединить с этим).

toonvanstrijp 13.04.2018 11:21

Я обновил свой ответ. Это то, что ты хочешь? И я заменил параметры в STR_TO_DATE('2016-12-01', '%Y-%m-%d').

Sergey Menshov 13.04.2018 11:38

Спасибо @ leran2002, но, как я уже сказал, мне нужен полный результат (строка) из ответов, которые запрашивали помощь между этими датами, поэтому я думаю, что мне понадобится соединение, я прав?

toonvanstrijp 13.04.2018 15:17

Простите. Думаю, я тебя неправильно понял. Я обновил второй запрос. Если вы хотите получить полную информацию об ответах, вам не нужно использовать GROUP BY и SUM.

Sergey Menshov 13.04.2018 17:11

И я думаю, вы можете везде использовать JOIN вместо LEFT JOIN. Попробуйте и это проверить.

Sergey Menshov 13.04.2018 17:17

Я добавил еще один запрос. Он возвращает только подробные строки для notComplete. Надеюсь, это то, что ты хочешь.

Sergey Menshov 13.04.2018 17:35

Спасибо! Это именно то, что мне нужно! :)

toonvanstrijp 15.04.2018 00:31

Другие вопросы по теме