MySQL — возвращает нескольких пользователей на основе членства в команде

#mysql #sql

#mysql #sql

Вопрос:

Я хочу вернуть всех, users которые являются членами teams , частью которых является запрошенный пользователь (имитируемый путем жесткого кодирования uid значения user1 ). Я пытаюсь достичь этого с помощью таблицы объединения teams_members , но в итоге могу получить только запросы, которые возвращают больше, чем то, что я ищу.

Ссылка на скрипку DB

В выводе запроса (запрос № 3) я ожидаю, что не увижу user3 , поскольку они не являются частью team1 или team2 единственными командами, в которые user1 входит.

Настройка:

 CREATE TABLE users (
  uid INT,
  name TEXT
);
INSERT INTO users (uid, name) VALUES (1, "user1");
INSERT INTO users (uid, name) VALUES (2, "user2");
INSERT INTO users (uid, name) VALUES (3, "user3");

CREATE TABLE teams (
  tuid INT,
  name TEXT
);
INSERT INTO teams (tuid, name) VALUES (1, 'team1');
INSERT INTO teams (tuid, name) VALUES (2, 'team2');
INSERT INTO teams (tuid, name) VALUES (3, 'team3');

CREATE TABLE teams_members (
  uid INT,
  tuid INT,
  role TEXT
);
INSERT INTO teams_members (uid, tuid, role) VALUES (1, 1, 'owner');
INSERT INTO teams_members (uid, tuid, role) VALUES (1, 2, 'owner');
INSERT INTO teams_members (uid, tuid, role) VALUES (2, 1, 'owner');
INSERT INTO teams_members (uid, tuid, role) VALUES (3, 3, 'owner');
  

Запросы (другие добавлены для контекста):

 # Get user
SELECT * FROM users WHERE uid = 1;

# Get teams the user is part of
SELECT t.tuid, t.name FROM teams t
LEFT JOIN teams_members tm ON t.tuid = tm.tuid
WHERE uid = 1;

# Get team members present for all teams <<<<<<< Query in question
SELECT u.uid, u.name FROM users u
LEFT JOIN teams_members tm ON u.uid = tm.uid
LEFT JOIN teams t ON tm.tuid = t.tuid
WHERE tm.uid = u.uid;
  

Как мне вернуть только users те, которые присутствуют в командах, которые user1 являются частью?

Ответ №1:

Ваш второй запрос — это все, что вам нужно. Используйте его для получения данных от пользователей таблицы:

 select * 
from users where uid in(SELECT t.tuid 
                        FROM teams t
                        LEFT JOIN teams_members tm ON t.tuid = tm.tuid
                        WHERE uid = 1);
  

Вот демонстрация:

ДЕМОНСТРАЦИЯ

Ответ №2:

Как мне вернуть только пользователей, присутствующих в командах, частью которых является пользователь1?

Один метод использует exists :

 select u.*
from users u
where exists (select 1
              from teams_members tm1 join
                   teams_members tm2
                   on tm1.tuid = tm2.tuid  -- same team
              where tm1.uid = 1 and        -- team has user 1
                    tm2.uid = u.uid        -- team has user in outer query
             );