MySQL - пропущены строки из-за вложенных NULL SELECT и JOIN - PullRequest
0 голосов
/ 11 октября 2018

У меня сейчас четыре таблицы: users, user_groups, user_group_memberships и user_group_permissions.user_group_memberships используется для связывания users.id с user_groups.user_id, а user_group_permissions используется для связывания членов группы со списком разрешений / прав.

Я хочу выполнить один запрос, которыйполучает массив всех групп из user_groups и в том же запросе получает количество членов в каждой группе из user_group_memberships, затем я хотел бы получить имя политики пользователя из user_group_permissions.

Запрос «работает», если каждый user_groups имеет членов в user_group_memberhips и если каждая запись user_groups имеет политику, установленную в user_group_permissions., Но это не вернет ни одной группы, которая еще неназначить участника или политику пользователя.Я неправильно понимаю обработку, если NULL или мой JOIN?

SELECT  ug.*, 
    (SELECT count(*) FROM user_group_memberships WHERE ug.id = ugm.group_id) AS member_count,
    (SELECT policy_name FROM user_group_permissions WHERE ugp.id = ug.user_policy_id) AS policy_name 
FROM 
    user_groups AS ug
LEFT JOIN 
    user_group_memberships AS ugm ON ug.id = ugm.group_id 
LEFT JOIN 
    user_group_permissions AS ugp ON ug.user_policy_id = ugp.id 
WHERE 
    ug.organisation_id=?


users
+----+-----------------+
| id | username        |
+----+-----------------+
|  1 | Thomas          |
|  2 | Harry           |
+----+-----------------+

user_groups
+----+-----------------+-------------------+------------+
| id | organisation_id | user_permission_id| group_name |
+----+-----------------+-------------------+------------+
|  1 | 123             |  1                | Finance    |
|  2 | 123             |  2                | Support    |
+----+-----------------+-------------------+------------+

user_group_memberships
+----+-----------------+----------+----------+
| id | organisation_id | user_id  | group_id |
+----+-----------------+----------+----------+
|  1 | 123             | 1        | 1        |
|  2 | 123             | 2        | 1        |
+----+-----------------+----------+----------+

user_group_permissions
+----+-----------------+
| id | policy_name     |
+----+-----------------+
|  1 | Finance         |
|  2 | Support         |
+----+-----------------+

Используя приведенный выше пример, я ожидаю, что мой запрос вернет две строки (по одной для каждой группы), с member_count = 2 для группы 1(строка 1) и member_count = 0 для группы 2 (строка 2).В настоящее время он возвращает только один для группы 1, так как member_count существует / не является нулевым.Он не возвращает данных для группы 2, поскольку в group_memberships нет записей для группы 2, удовлетворяющих COUNT ().

Та же проблема возникает, когда user_groups.user_permissions_id имеет значение NULL, она будет возвращать запись группы только в том случае, если в группе есть участники и если для группы установлен user_permission_id.

1 Ответ

0 голосов
/ 11 октября 2018

Использование коррелированных подзапросов неверно.Кроме того, чтобы получить количество участников, вам не нужно использовать подзапрос;Вы можете использовать Group by с Count().

Попробуйте:

SELECT ug.id,  
       ug.organisation_id, 
       ug.group_name, 
       COUNT(ugm.group_id) AS member_count,
       ugp.policy_name 
FROM 
    user_groups AS ug
LEFT JOIN 
    user_group_memberships AS ugm ON ug.id = ugm.group_id 
LEFT JOIN 
    user_group_permissions AS ugp ON ug.user_policy_id = ugp.id   
WHERE 
    ug.organisation_id=? 
GROUP BY 
  ug.id, 
  ug.organisation_id, 
  ug.group_name, 
  ugp.policy_name 
...