Показать все результаты из одной таблицы, не включенной в другую таблицу (Junction) By: id

621
Midnight-Coding

У меня есть 2 таблицы, с которыми я взаимодействую.

Первая таблица: acl_permissions (это просто обычная таблица).

+-----------------------------------+ | acl_permissions | +----+-------------+----------------+ | id | name | permission | +----+-------------+----------------+ | 1 | Add User | addUser | | 2 | Edit User | editUser | | 3 | Delete User | deleteUser | | 4 | View User | viewUser | | 5 | Test Name | testPermission | +----+-------------+----------------+ 

Вторая таблица: acl_group_permissions - это таблица соединений.

+--------------------------------+ | acl_group_permissions | +----+----------+----------------+ | id | group_id | permissions_id | +----+----------+----------------+ | 1 | 1 | 1 | | 2 | 1 | 2 | | 3 | 1 | 3 | | 4 | 1 | 4 | | 5 | 2 | 4 | | 6 | 2 | 5 | +----+----------+----------------+ 

У меня есть запрос, чтобы показать все разрешения, которые в настоящее время разрешены group_id '1'.

SELECT acl_permissions.id, acl_permissions.name, acl_permissions.permission FROM acl_permissions JOIN acl_group_permissions ON acl_permissions.id = acl_group_permissions.permission_id WHERE acl_group_permissions.group_id = 1 

Результат:

+----+-------------+----------------+ | id | name | permission | +----+-------------+----------------+ | 1 | Add User | addUser | | 2 | Edit User | editUser | | 3 | Delete User | deleteUser | | 4 | View User | viewUser | +----+-------------+----------------+ 

МОЯ ПРОБЛЕМА

Я хочу, чтобы запрос показывал все разрешения, которые не разрешены group_id '1'.

Желаемый результат будет:

+----+-------------+----------------+ | id | name | permission | +----+-------------+----------------+ | 5 | Test Name | testPermission | +----+-------------+----------------+ 

Самое близкое, что я должен к этому:

SELECT acl_permissions.id, acl_permissions.name, acl_permissions.permission FROM acl_permissions LEFT OUTER JOIN acl_group_permissions ON acl_permissions.id = acl_group_permissions.permission_id WHERE acl_group_permissions.group_id IS NULL 

В результате получается:

+----+-------------+----------------+ | id | name | permission | +----+-------------+----------------+ | 4 | View User | viewUser | | 5 | Test Name | testPermission | +----+-------------+----------------+ 

Как мне вставить group_id '1' в запрос, чтобы устранить идентификатор 4.

Я много гуглил, но я нахожу примеры и решения, которые близки, но точны к моей ситуации.

IE: используя соединительную таблицу. Моя инфографика MySQL Join Types также не поможет.

Помогите..! Мой мозг тает ..!

1

3 ответа на вопрос

0
skv

Not the best, but this would work

SELECT acl_permissions.id, acl_permissions.name, acl_permissions.permission FROM acl_permissions JOIN acl_group_permissions ON acl_permissions.id = acl_group_permissions.permission_id WHERE acl_group_permissions.group_id != 1 and acl_permissions.id NOT IN (SELECT DISTINCT acl_permissions.id FROM acl_permissions JOIN acl_group_permissions ON acl_permissions.id = acl_group_permissions.permission_id WHERE acl_group_permissions.group_id = 1) 
0
Zimmi

Don’t use a join logic, use instead a simpler one :

Select all permissions_id that group_1 has (from acl_group_permissions), then select all acl_permissions id that are not in the ones selected. Translated to SQL, it becomes:

SELECT acl_permissions.id, acl_permissions.name, acl_permissions.permission FROM acl_permissions WHERE acl_permissions.id NOT IN ( SELECT permissions_id FROM acl_group_permissions WHERE group_id = 1 ) 
Спасибо. Понятно, логично и задним числом очевидно. Теперь я знаю все о НЕ IN. Midnight-Coding 9 лет назад 0
0
RolandoMySQLDBA

ПРЕДЛАГАЕМЫЙ ЗАПРОС

SELECT A.* FROM acl_permissions A LEFT JOIN (SELECT * FROM acl_group_permissions WHERE group_id=1) B ON A.id = B.permissions_id WHERE B.id IS NULL; 

ВАШИ ОБРАЗЦЫ ДАННЫХ

DROP DATABASE IF EXISTS matt; CREATE DATABASE matt; USE matt CREATE TABLE acl_permissions ( id int not null auto_increment, name varchar(32), permission varchar(32), primary key (id) ); CREATE TABLE acl_group_permissions ( id int not null auto_increment, group_id int not null, permissions_id int not null, primary key (id) ); INSERT INTO acl_permissions (name,permission) VALUES ('Add User' ,'addUser'), ('Edit User' ,'editUser'), ('Delete User','deleteUser'), ('View User' ,'viewUser'), ('Test Name' ,'testPermission'); INSERT INTO acl_group_permissions (group_id,permissions_id) VALUES (1,1),(1,2),(1,3),(1,4),(2,4),(2,5); SELECT * FROM acl_permissions; SELECT * FROM acl_group_permissions; 

Загружены ваши образцы данных

mysql> DROP DATABASE IF EXISTS matt; Query OK, 2 rows affected (0.39 sec)  mysql> CREATE DATABASE matt; Query OK, 1 row affected (0.00 sec)  mysql> USE matt Database changed mysql> CREATE TABLE acl_permissions -> ( -> id int not null auto_increment, -> name varchar(32), -> permission varchar(32), -> primary key (id) -> ); Query OK, 0 rows affected (0.29 sec)  mysql> CREATE TABLE acl_group_permissions -> ( -> id int not null auto_increment, -> group_id int not null, -> permissions_id int not null, -> primary key (id) -> ); Query OK, 0 rows affected (0.30 sec)  mysql> INSERT INTO acl_permissions -> (name,permission) VALUES -> ('Add User' ,'addUser'), -> ('Edit User' ,'editUser'), -> ('Delete User','deleteUser'), -> ('View User' ,'viewUser'), -> ('Test Name' ,'testPermission'); Query OK, 5 rows affected (0.03 sec) Records: 5 Duplicates: 0 Warnings: 0  mysql> INSERT INTO acl_group_permissions -> (group_id,permissions_id) VALUES -> (1,1),(1,2),(1,3),(1,4),(2,4),(2,5); Query OK, 6 rows affected (0.08 sec) Records: 6 Duplicates: 0 Warnings: 0  mysql> SELECT * FROM acl_permissions; +----+-------------+----------------+ | id | name | permission | +----+-------------+----------------+ | 1 | Add User | addUser | | 2 | Edit User | editUser | | 3 | Delete User | deleteUser | | 4 | View User | viewUser | | 5 | Test Name | testPermission | +----+-------------+----------------+ 5 rows in set (0.00 sec)  mysql> SELECT * FROM acl_group_permissions; +----+----------+----------------+ | id | group_id | permissions_id | +----+----------+----------------+ | 1 | 1 | 1 | | 2 | 1 | 2 | | 3 | 1 | 3 | | 4 | 1 | 4 | | 5 | 2 | 4 | | 6 | 2 | 5 | +----+----------+----------------+ 6 rows in set (0.00 sec)  mysql> 

ПРЕДЛАГАЕМЫЙ ЗАПРОС ИСПОЛНЕНО

mysql> SELECT A.* -> FROM acl_permissions A LEFT JOIN -> (SELECT * FROM acl_group_permissions WHERE group_id=1) B -> ON A.id = B.permissions_id WHERE B.id IS NULL; +----+-----------+----------------+ | id | name | permission | +----+-----------+----------------+ | 5 | Test Name | testPermission | +----+-----------+----------------+ 1 row in set (0.00 sec)  mysql> 

ДАЙТЕ ПОПРОБУЙТЕ !!!

Вот это да..! Мне нравится ваш системный подход к ответу на мой вопрос, и ваш ответ работает ..! Единственная причина, по которой я не принял это как ответ, - это сложность по сравнению с другими. Я никогда не видел такой запрос. У меня есть намного больше, чтобы учиться. +1 за вашу логику и представление. Midnight-Coding 9 лет назад 0