powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Упростить запрос
14 сообщений из 14, страница 1 из 1
Упростить запрос
    #40083790
LiYing
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день! Как можно избавиться от 4х однотипных подзапросов в следующем запросе:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
SELECT i.name,
 (SELECT COUNT(r.id) FROM requests r 
  INNER JOIN users u ON r.id_user_opened=u.id AND u.id_department=1
  WHERE r.id_issue=i.id) cnt_1,
 (SELECT COUNT(r.id) FROM requests r 
  INNER JOIN users u ON r.id_user_opened=u.id AND u.id_department=2
  WHERE r.id_issue=i.id) cnt_2,
 (SELECT COUNT(r.id) FROM requests r 
  INNER JOIN users u ON r.id_user_opened=u.id AND u.id_department=3
  WHERE r.id_issue=i.id) cnt_3,
 (SELECT COUNT(r.id) FROM requests r 
  INNER JOIN users u ON r.id_user_opened=u.id AND u.id_department=4
  WHERE r.id_issue=i.id) cnt_4
FROM issues i


Суть: выбрать все типы заявок i.name из таблицы issues i . Далее из таблицы заявок requests r подсчитать кол-во однотипных заявок, зарегистрированных пользователем (из таблицы users u ), который числится в одном из 4х отделов ( u.id_department =1..4), с разбивкой по отделам.

Пример результата:
namecnt_1cnt_2cnt_3cnt_4тип заявки №10000тип заявки №20001тип заявки №30100тип заявки №41000
Для тестовых таблиц:
users
idid_departmentname34Тестов В.Н.282Иванов Л.А.291Петров И.Ю.
issues
idname1тип заявки №12тип заявки №23тип заявки №34тип заявки №4
requests
idid_issueid_user_opened12323283429
...
Рейтинг: 0 / 0
Упростить запрос
    #40084088
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не просто можно. Нужно.

Связать все три таблицы. И считать SUM(u.id_department=X) AS sum_X
...
Рейтинг: 0 / 0
Упростить запрос
    #40084117
LiYing
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina,
спасибо за подсказку!
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
SELECT i.name,
 COALESCE(SUM(u.id_department=1), 0) cnt_1,
 COALESCE(SUM(u.id_department=2), 0) cnt_2,
 COALESCE(SUM(u.id_department=3), 0) cnt_3,
 COALESCE(SUM(u.id_department=4), 0) cnt_4
FROM issues i
LEFT JOIN requests r ON i.id=r.id_issue
LEFT JOIN users u ON r.id_user_opened=u.id
GROUP BY i.id


Я правильно понял, так? Дает нужный результат, еще более упростить вроде нельзя...
...
Рейтинг: 0 / 0
Упростить запрос
    #40084227
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
С формальной точки зрения группировать надо всё-таки по i.name . Либо, если построитель не справится, по i.id, i.name .
...
Рейтинг: 0 / 0
Упростить запрос
    #40084236
LiYing
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina
С формальной точки зрения группировать надо всё-таки по i.name . Либо, если построитель не справится, по i.id, i.name .

А есть ли смысл, если по i.id первичный ключ, а i.name уникально?
...
Рейтинг: 0 / 0
Упростить запрос
    #40084240
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LiYing
i.name уникально
Это после JOIN-а то ?
...
Рейтинг: 0 / 0
Упростить запрос
    #40084242
LiYing
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
miksoft
LiYing
i.name уникально
Это после JOIN-а то ?

Эээ..., а причем тут JOIN? Я имел в виду в таблице уникально. Чего я не понимаю, объясните плиз.
...
Рейтинг: 0 / 0
Упростить запрос
    #40084245
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LiYing
miksoft
пропущено...
Это после JOIN-а то ?

Эээ..., а причем тут JOIN? Я имел в виду в таблице уникально. Чего я не понимаю, объясните плиз.
JOIN может размножить записи. И i.name перестанет быть уникальным.
...
Рейтинг: 0 / 0
Упростить запрос
    #40084254
LiYing
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
miksoft
JOIN может размножить записи. И i.name перестанет быть уникальным.

Как можно смоделировать такую ситуацию, не подскажете?
...
Рейтинг: 0 / 0
Упростить запрос
    #40084273
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LiYing
miksoft
JOIN может размножить записи. И i.name перестанет быть уникальным.

Как можно смоделировать такую ситуацию, не подскажете?
Например, если поле users.id окажется неуникальным.
...
Рейтинг: 0 / 0
Упростить запрос
    #40084323
LiYing
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
miksoft
LiYing
пропущено...

Как можно смоделировать такую ситуацию, не подскажете?
Например, если поле users.id окажется неуникальным.

Вопрос: неуникальным где? Для теста добавил в issues еще 3 записи, а в requests две. Если в таблице requests в поле id_user_opened проставить всем один id , то оба запроса (разница в поле группировки):
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
#1
SELECT i.name,
 COALESCE(SUM(u.id_department=1), 0) cnt_1,
 COALESCE(SUM(u.id_department=2), 0) cnt_2,
 COALESCE(SUM(u.id_department=3), 0) cnt_3,
 COALESCE(SUM(u.id_department=4), 0) cnt_4
FROM issues i
LEFT JOIN requests r ON i.id=r.id_issue
LEFT JOIN users u ON r.id_user_opened=u.id
GROUP BY i.id

#2
SELECT i.name,
 COALESCE(SUM(u.id_department=1), 0) cnt_1,
 COALESCE(SUM(u.id_department=2), 0) cnt_2,
 COALESCE(SUM(u.id_department=3), 0) cnt_3,
 COALESCE(SUM(u.id_department=4), 0) cnt_4
FROM issues i
LEFT JOIN requests r ON i.id=r.id_issue
LEFT JOIN users u ON r.id_user_opened=u.id
GROUP BY i.name


дают одинаковый результат. Но explain у них разный (по i.name индекса нет):
#1
idselect_typetablepartitionstypepossible_keyskeykey_lenrefrowsfilteredExtra1SIMPLEiNULLindexPRIMARYPRIMARY4NULL6100.00NULL1SIMPLErNULLrefid_issueid_issue5call_center.i.id1100.00NULL1SIMPLEuNULLeq_refPRIMARYPRIMARY4call_center.r.id_user_opened1100.00NULL
#2
idselect_typetablepartitionstypepossible_keyskeykey_lenrefrowsfilteredExtra1SIMPLEiNULLALLNULLNULLNULLNULL6100.00Using temporary1SIMPLErNULLrefid_issueid_issue5call_center.i.id1100.00NULL1SIMPLEuNULLeq_refPRIMARYPRIMARY4call_center.r.id_user_opened1100.00NULL
Поймите меня правильно - я "не докапываюсь", просто пытаюсь разобраться...
...
Рейтинг: 0 / 0
Упростить запрос
    #40084354
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Но explain у них разный (по i.name индекса нет):
Вот я и говорю, что построитель может не справиться.

А есть ли смысл, если по i.id первичный ключ, а i.name уникально?
Формально - выходное выражение либо входит в выражение группировки, либо является аргументом агрегатной функции. И первичный ключ, группирующий по другим полям таблицы - это не стандарт, а расширение.
...
Рейтинг: 0 / 0
Упростить запрос
    #40084358
LiYing
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina
Формально - выходное выражение либо входит в выражение группировки, либо является аргументом агрегатной функции. И первичный ключ, группирующий по другим полям таблицы - это не стандарт, а расширение.

Формально - да, но фактически выходит, что группировка по первичному ключу отрабатывает на 100% верно в данном запросе. По-крайней мере, какие бы вариации исходных таблиц я не пробовал, результат при GROUP BY i.id и GROUP BY i.name одинаков. И план при этом предпочтительнее получается для GROUP BY i.id. Но формально запрос некорректен, уфф...
...
Рейтинг: 0 / 0
Упростить запрос
    #40084435
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот потому я и предлагаю GROUP BY i.id, i.name . Это обеспечит и синтаксическую корректность, и правильный план.
...
Рейтинг: 0 / 0
14 сообщений из 14, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Упростить запрос
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]