В MYSQL, как я могу получить LEFT JOIN для возврата каждой строки в одной таблице и флаг, если в другой таблице были какие-либо совпадающие строки? - PullRequest
2 голосов
/ 11 апреля 2011

В основном у меня есть две таблицы: admin_privilege и admin_roll_privilege.Я пытаюсь написать запрос, чтобы получить каждую строку из admin_privilege, и если в admin_roll_privilege есть строка с совпадающим admin_privilege_id И совпадающим admin_roll_id, чтобы установить для нового столбца значение 1. Пока у меня есть это:

  SELECT ap.*, 
    IF(arp.admin_privilege_id IS NULL,0,1) AS has_privilege
  FROM admin_privilege ap LEFT JOIN admin_roll_privilege arp
    ON ap.admin_privilege_id=arp.admin_privilege_id
  WHERE arp.admin_roll_id=3 
    OR arp.admin_roll_id IS NULL;

Это работает во всех случаях, кроме случаев, когда нет совпадающих строк admin_roll_privilege.

См. Пример:

+---------------+--------------------+
| admin_roll_id | admin_privilege_id |
+---------------+--------------------+
|             1 |                  2 |
|             1 |                  3 |
+---------------+--------------------+

+--------------------+------------------------+
| admin_privilege_id | admin_privilege_name   |
+--------------------+------------------------+
|                  1 | Access Developer Tools |
|                  4 | Edit System Settings   |
|                  2 | Edit User Profiles     |
|                  3 | Resolve Challenges     |
+--------------------+------------------------+

Запрос WHERE admin roll id = 1 работает должным образом:

+--------------------+------------------------+---------------+
| admin_privilege_id | admin_privilege_name   | has_privilege |
+--------------------+------------------------+---------------+
|                  1 | Access Developer Tools |             0 |
|                  4 | Edit System Settings   |             0 |
|                  2 | Edit User Profiles     |             1 |
|                  3 | Resolve Challenges     |             1 |
+--------------------+------------------------+---------------+

Но, если я запрашиваю admin_roll_id = 3, я получу только две возвращенные строки:

+--------------------+------------------------+---------------+
| admin_privilege_id | admin_privilege_name   | has_privilege |
+--------------------+------------------------+---------------+
|                  1 | Access Developer Tools |             0 |
|                  4 | Edit System Settings   |             0 |
+--------------------+------------------------+---------------+

Как я могу получить этот запрос, чтобы вернуть все 4?

Редактировать: это то, что в итоге сработало, переместив условие в условие on:

SELECT ap.*, 
    IF(arp.admin_privilege_id IS NULL,0,1) AS has_privilege
  FROM admin_privilege ap LEFT JOIN admin_roll_privilege arp
    ON (ap.admin_privilege_id=arp.admin_privilege_id AND arp.admin_roll_id=1)

Ответы [ 2 ]

2 голосов
/ 11 апреля 2011

Переместите соответствующие условия из предложения WHERE в предложение ON.

1 голос
/ 11 апреля 2011

Вы не возвращаете все строки, используя предложение WHERE для всего оператора.
Превратите LEFT JOIN в подвыбор, к которому можно добавить необходимое предложение WHERE.

SELECT  ap.admin_privilege_id
        , ap.admin_privilege_name
        , IF(arp.admin_privilege_id IS NULL,0,1) AS has_privilege
FROM    admin_privilege ap
        LEFT OUTER JOIN (
          SELECT  admin_privilege_id
          FROM    admin_roll_privilege arp
          WHERE   arp.admin_roll_id = 3
        ) arp ON arp.admin_privilege_id = ap.admin_privilege_id
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...