Как опустить результаты выбора на основе идентификаторов из другой таблицы в MySQL? - PullRequest
1 голос
/ 09 января 2012

Моя цель состоит в том, чтобы я хотел получить список имен пользователей в базе данных из моей таблицы "users", но опустить каждого пользователя, чей ID также находится в таблице "projects_users", где project_id = 1.

Другими словами, если это таблицы:

table: users
user_id   user_name
1         dave
2         matt
3         james

table: projects_users
user_id   project_id
1         2
2         2
3         1

Этот запрос вернул бы "dave" и "matt" (поскольку "james" находится в таблице пользователей, но также связан с проектом # 1, поэтому он опущен).

Я понимаю, что, вероятно, мне следует использовать какую-то форму соединения, но мой текущий запрос не делает этого:

SELECT user_name
FROM users
JOIN projects_users ON (
    users.user_id != (projects_users.user_id WHERE projects_users.user_id == 1)
)

Этот результат не работает вообще, и более ранние эксперименты продолжали возвращать несколько копий каждого имени. Кто-нибудь знает способ сделать это, не обращаясь к более ручному решению PHP?

Ответы [ 4 ]

2 голосов
/ 10 января 2012

Окончательный ответ, отлично сработало.Может быть, это не так оптимизировано, как некоторые другие решения, но это единственное, которое каждый раз дало мне достоверные результаты.По какой-то причине другие решения иногда выдавали неожиданное имя или вообще не указывали имя, когда им следовало бы иметь.Несмотря на это, это, безусловно, лучше, чем проделывать долгий путь с PHP.

SELECT user_id, user_name FROM users WHERE user_id NOT IN (SELECT user_id FROM projects_users WHERE project_id = 1)

Спасибо всем за ваш вклад.Я ценю всю вашу помощь и вклад.

1 голос
/ 09 января 2012

попробуйте это:

SELECT DISTINCT
    users.user_id,
    user_name
FROM
    projects_users
RIGHT JOIN
    users
ON
    users.user_id = projects_users.user_id
WHERE
    projects_users.project_id <> 1
OR
    projects_users.project_id IS NULL
1 голос
/ 09 января 2012

Оригинальный ответ

Используйте силу LEFT JOIN.

SELECT u.* 
FROM users u
LEFT JOIN project_users pu ON u.user_id = pu.user_id
WHERE pu.project_id IS NULL OR pu.project_id <> 1;

В отличие от JOIN (что является ярлыком для INNER JOIN), LEFT JOIN выбирает все строки из основной таблицы и соответствующие им строки из объединенной таблицы, НО, если соответствующая строка не найдена, возвращается поддельная строка с все поля установлены на NULL.

Редактировать

Когда я перечитал вопрос, мне показалось, что я ошибся. Если вы хотите отфильтровать только пользователей, связанных с определенным проектом, то этот запрос нужно использовать.

SELECT DISTINCT u.user_id, u.user_name 
FROM project_users pu
LEFT JOIN users u ON u.user_id = pu.user_id
WHERE pu.project_id <> 1;
0 голосов
/ 09 января 2012

Попробуйте следующее:

select u.*
from users u
where exists (select null 
              from projects_users pu1 
              where u.user_id = pu1.user_id)
and not exists (select null 
                from projects_users pu2 
                where u.user_id = pu2.user_id and pu2.project_id = 1)

В качестве альтернативы:

select u.*
from users u
join projects_users pu on u.user_id = pu.user_id
group by u.user_id
having max(case when pu.project_id = 1 then 1 else 0 end) = 0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...