MySQL: переопределить группы пользователей из описания групп - PullRequest
0 голосов
/ 13 декабря 2018


У меня проблема с поиском членов группы для пользователей.(да, это не очень понятно)
Например:
У меня есть 2 таблицы:
- один содержит список пользователей с их разрешением:

userId | permission
-------|-----------
1      | build
1      | play
1      | jump
2      | build
2      | jump
2      | run
3      | drink
3      | build
4      | run

- вторая таблица содержитгруппа и его разрешение:

groupId | permission
--------|-----------
G1      | build
G1      | jump
G2      | play
G2      | jump
G3      | drink
G3      | run
G4      | drink
G5      | build

Моя цель - найти все группы, которые может иметь пользователь:

userId | groupId
-------|-----------
1      | G1
1      | G2
1      | G5
2      | G1
2      | G5
3      | G4
3      | G5

Я создал запрос, чтобы найти пользователейпринадлежат группе, но я не могу сделать это для всех моих групп (у меня более 1000 групп в моих наборах данных):

SELECT DISTINCT userId
FROM (
       SELECT userId, count(*) AS nbData
       from table_a
       WHERE permission in (
         SELECT permission
         from table_b
         where groupId = 'g1'
       )
       group by userId
     ) as t
where nbData = (SELECT count(*) from table_b where groupId = 'g1');

Пользователь принадлежит группе, если у него есть все разрешения группы,И цель состоит в том, чтобы найти каждую группу каждого пользователя

Ответы [ 3 ]

0 голосов
/ 13 декабря 2018

Если у вас нет дубликатов ни в одной из таблиц, вы можете объединить таблицы вместе по разрешениям и агрегировать:

select up.userId, gp.groupId
from user_permissions up join
     group_permissions gp
     on up.permission = gp.permission
group by up.userId, gp.groupId
having count(*) = (select count(*)
                   from group_permissions gp2
                   where gp2.groupId = gp.groupId
                  );

Пользователь входит в группу, если все разрешения для группы совпадают.

0 голосов
/ 13 декабря 2018

Например:

DROP TABLE IF EXISTS user_permissions;

CREATE TABLE user_permissions
(user_id INT NOT NULL
,permission VARCHAR(12) NOT NULL
,PRIMARY KEY(user_id,permission)
);

INSERT INTO user_permissions VALUES
(1,'build'),
(1,'play'),
(1,'jump'),
(2,'build'),
(2,'jump'),
(2,'run'),
(3,'drink'),
(3,'build'),
(4,'run');

DROP TABLE IF EXISTS group_permissions;

CREATE TABLE group_permissions
(group_id INT NOT NULL
,permission VARCHAR(12) NOT NULL
,PRIMARY KEY(group_id,permission)
);

INSERT INTO group_permissions VALUES
(101,'build'),
(101,'jump'),
(102,'play'),
(102,'jump'),
(103,'drink'),
(103,'run'),
(104,'drink'),
(105,'build');

SELECT DISTINCT u.user_id
              , g.group_id 
           FROM user_permissions u 
           JOIN group_permissions g 
             ON g.permission = u.permission -- groups that users potentially belong to
           LEFT 
           JOIN 
              ( SELECT DISTINCT x.user_id
                              , y.group_id 
                           FROM user_permissions x 
                           LEFT 
                           JOIN group_permissions y 
                             ON y.permission = x.permission 
                           LEFT 
                           JOIN group_permissions z 
                             ON z.group_id = y.group_id 
                           LEFT 
                           JOIN user_permissions a 
                             ON a.user_id = x.user_id 
                            AND a.permission = z.permission 
                          WHERE a.user_id IS NULL
              ) n -- groups that users don't belong to (this could be much simpler ;-) )
             ON n.user_id = u.user_id 
            AND n.group_id = g.group_id 
          WHERE n.user_id IS NULL;
+---------+----------+
| user_id | group_id |
+---------+----------+
|       1 |      101 |
|       1 |      105 |
|       1 |      102 |
|       2 |      101 |
|       2 |      105 |
|       3 |      105 |
|       3 |      104 |
+---------+----------+
0 голосов
/ 13 декабря 2018

Примерно так может работать:

SELECT DISTINCT
    a.userId,
    b.groupId
FROM
    table_a a
    JOIN table_b b 
        ON a.permission = b.permission
...