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

0

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

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

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

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

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
  • 0
    Поиск условной агрегации. И вы можете улучшить свой вопрос, добавив образцы данных и ожидаемый результат в виде текста или sqlfiddle.
Теги:
performance

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, вы можете поместить все необходимые условия в ГДЕ

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
  • 0
    Спасибо!!! Тогда еще одна вещь, что если я хочу фильтровать между датами? Макет базы данных дерьмовый, поэтому я должен сделать это, чтобы получить данные при планировании задачи: hastebin.com/jizecoqevu.sql Дело в том, что мне нужны полные строки для required_help_at, поэтому должно быть какое-то право на объединение ? (тогда у меня есть еще два запроса для объединения с этим).
  • 0
    Я обновил свой ответ. Это то, что вы хотите? И я заменил параметры на STR_TO_DATE('2016-12-01', '%Y-%m-%d') .
Показать ещё 5 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню