SQL множественные инклюзивные соединения

#sql #join

#sql #Присоединиться

Вопрос:

Ниже приведено описание схемы. Я хотел бы создать запрос, который для данного пользователя вернет все обращения, которые передаются напрямую case_users или косвенно через case_groups таблицу. Вот моя попытка, в которой я заранее выбираю группы, к которым принадлежит пользователь:

 SELECT * FROM `cases` 
INNER JOIN `case_users` ON `cases`.`id` = `case_users`.`case_id` 
INNER JOIN `case_groups` ON `cases`.`id` = `case_groups`.`case_id` 
WHERE `case_users`.`user_id` = '<USER_ID>' 
OR `case_groups`.`group_id` IN (<USER_GROUP_LIST>)
 

EXPLAIN возвращает следующее: Impossible WHERE noticed after reading const table...

Как я могу это сделать? В идеале я хотел бы получить все обращения за один раз — без извлечения USER_GROUP_LIST — групп, к которым принадлежит пользователь.

 mysql> describe users;
 ------------- -------------- ------ ----- --------- ---------------- 
| Field       | Type         | Null | Key | Default | Extra          |
 ------------- -------------- ------ ----- --------- ---------------- 
| id          | int(11)      | NO   | PRI | NULL    | auto_increment |
 ------------- -------------- ------ ----- --------- ---------------- 

mysql> describe cases;
 ------------- -------------- ------ ----- --------- ---------------- 
| Field       | Type         | Null | Key | Default | Extra          |
 ------------- -------------- ------ ----- --------- ---------------- 
| id          | int(11)      | NO   | PRI | NULL    | auto_increment |
 ------------- -------------- ------ ----- --------- ---------------- 

mysql> describe case_users;
 ------------- --------- ------ ----- --------- ------- 
| Field       | Type    | Null | Key | Default | Extra |
 ------------- --------- ------ ----- --------- ------- 
| user_id     | int(11) | NO   | PRI | NULL    |       |
| case_id     | int(11) | NO   | PRI | NULL    |       |
 ------------- --------- ------ ----- --------- ------- 

mysql> describe case_groups;
 ------------- --------- ------ ----- --------- ------- 
| Field       | Type    | Null | Key | Default | Extra |
 ------------- --------- ------ ----- --------- ------- 
| case_id     | int(11) | NO   | PRI | NULL    |       |
| group_id    | int(11) | NO   | PRI | NULL    |       |
 ------------- --------- ------ ----- --------- ------- 

mysql> describe group_users;
 ------------- --------- ------ ----- --------- ------- 
| Field       | Type    | Null | Key | Default | Extra |
 ------------- --------- ------ ----- --------- ------- 
| group_id    | int(11) | NO   | PRI | NULL    |       |
| user_id     | int(11) | NO   | PRI | NULL    |       |
 ------------- --------- ------ ----- --------- ------- 
 

Ответ №1:

Ваши объединения будут возвращать только обращения, идентификатор которых находится как в case_users, так и в case_groups .. Если это один или другой, то вам нужно 2 запроса, которые вы можете объединить, чтобы получить все результаты в одном результирующем наборе:

 SELECT `cases`.* FROM `cases` 
INNER JOIN `case_users` ON `cases`.`id` = `case_users`.`case_id` 
WHERE `case_users`.`user_id` = '<USER_ID>' 
UNION
SELECT `cases`.* FROM `cases` 
INNER JOIN `case_groups` ON `cases`.`id` = `case_groups`.`case_id` 
WHERE `case_groups`.`group_id` IN (SELECT `group_users`.`group_id`
                                   FROM `group_users`
                                   WHERE `group_users`.`user_id` = '<USER_ID>')
 

Комментарии:

1. Может быть, вы можете добавить подзапрос, который извлекает USER_GROUP_LIST ? Я думаю, что это часть вопроса (как получить список в том же запросе, без отдельного перехода).

2. Case-user и case-group имеют разную структуру, но их файлы включены в результат. Возможно, вы хотите уточнить запрос.

3. Спасибо, именно такой запрос я в конечном итоге использовал.