Получить обратную ссылку?

Я использую 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% пути.