Получить обратную ссылку?
Я использую SQL Server 2005. У меня есть три таблицы - пользователи, группы и группы пользователей. GroupUsers содержит два PK для отношения "многие ко многим".
У меня есть возможность получить всю информацию о пользователе для группы следующим образом:
SELECT * FROM GroupUsers JOIN Users ON GroupUsers.UserID = Users.UserId
Я хочу создать обратное этому представлению - мне нужен список всех пользователей, не привязанных к определенной группе. Следующий запрос выполнит следующее:
SELECT * FROM Users WHERE UserID NOT IN
(SELECT UserID FROM GroupUsers WHERE [email protected])
Однако я не хочу указывать группу, я хочу знать, как превратить это в представление, которое объединяет идентификатор GroupID, а затем UserID и всю информацию о пользователе, но только для не подключенных пользователей.
Я не уверен, как это сделать, может быть, что-то с оператором EXCEPT?
UPDATE:
Я думаю, что это мое решение, если кто-то не придумает что-то лучшее:
SELECT
G.GroupId,
U.*
FROM
Groups G
CROSS JOIN
Users U
WHERE
U.UserId NOT IN
(
SELECT
UserId
FROM
GroupUsers
WHERE
GroupId=G.GroupId
)
Ответы
Ответ 1
Если я правильно понимаю, вам придется сделать картельский результат для пользователей и групп и уменьшить результат, полученный от GroupUsers.
Это даст вам записи о пользователях, которые не имеют к ней групп.
Прошу прощения, если я не понял вопрос правильно.
EDIT: декартовый результат даст вам группы пользователей. Вам придется вычесть из него GroupUsers. Извините, у меня нет SQL для этого и не могу попробовать это на данный момент.
Ответ 2
Вы можете использовать left outer join
, чтобы захватить всех пользователей, а затем убрать любого пользователя, где есть группа. Следующий запрос предоставит вам список пользователей, в которых нет группы:
select
u.*
from
users u
left outer join groupusers g on
u.userid = g.userid
where
g.userid is null
Если вы хотите найти всех пользователей не в определенной группе:
select
u.*
from
users u
left outer join groupusers g on
u.userid = g.userid
and g.groupid = @GroupID
where
g.userid is null
Это исключает пользователей только в этой группе. Каждый другой пользователь будет возвращен. Это связано с тем, что условие groupid
было выполнено в предложении join
, которое ограничивает присоединенные строки, а не возвращает их, что и делает предложение where
.
Ответ 3
Я не мог понять, как заставить предыдущую версию работать через активную запись, получил некоторые из них, но должен был написать инструкцию SQL. Я считаю, что это также выполняет то же самое.
SELECT * FROM Users WHERE UserID NOT IN
(SELECT U.UserID FROM GroupUsers AS G, Users as U WHERE G.UserID <> U.UserID)
Не удалось проверить, однако этот запрос в рельсах работал просто отлично:
# Gets Pre-Clients. Has client information but no project attached
Contact.joins(:client).includes(:projects => :primary_contact).
where("contacts.id NOT IN (select contacts.id from contacts,
projects where projects.primary_contact_id = contacts.id)")
Спасибо за сообщение, получил мне 90% пути.