选择特定用户不存在的行

时间:2016-12-16 00:43:19

标签: sql

我有4个表(用户,配置,字段,可用字段)

用户的相关架构是

UserID uniqueidentifier NOT NULL PRIMARY_KEY

配置的相关架构是

ConfigID uniqueidentifier NOT NULL PRIMARY KEY
UserID uniqueidentifier NOT NULL FOREIGN KEY (User.UserID)

Field的相关架构是

FieldID uniqueidentifier NOT NULL PRIMARY KEY
AvailableFieldID uniqueidentifier NOT NULL FOREIGN KEY (AvailableFields.AvailableFieldsID)
ConfigID uniqueidentifier NOT NULL FOREIGN KEY (Config.ConfigID)

AvailableFields相关架构是

AvailableFieldID uniqueidentifier NOT NULL PRIMARY KEY

我正在尝试返回他们在Fields表中没有的特定用户的所有可用字段。

有没有办法通过加入来做到这一点?

我看不到方法,因为模板AvailableFields表之间的唯一链接是AvailableFieldID,它是Fields表中的外键。

5 个答案:

答案 0 :(得分:1)

是的,使用INNER JOIN函数将Config作为第一个表,使用Field作为第二个表,以便为所有用户提供Config条目。然后使用RIGHT JOIN选择所有可用的字段条目,并省略没有可用字段条目的用户。

然后使用WHERE AvailableFields.AvailableFieldID IS NULL进行所有选择。这将表与Field / Config表的所有结果相连接。然后,它选择没有AvailableFields条目的用户。

<强>代码:

SELECT *
FROM Config
INNER JOIN Field ON Config.ConfigID = Field.ConfigID
RIGHT JOIN AvailableFields ON AvailableFields.AvailableFieldID = Field.AvailableFieldID
WHERE Field.UserID IS NULL

这将返回AvailableFields中没有相应Field条目的所有条目(即无用户)。

答案 1 :(得分:0)

我认为最直观的方法是将NOT IN与子查询一起使用:

SELECT * from AvailableField
WHERE AvailableField.AvailableFieldId NOT IN
    (SELECT AvailableFieldId FROM Field
    INNER JOIN Config ON Config.ConfigId = Field.ConfigId
    WHERE Config.UserId = ?)

其中?是您感兴趣的用户ID的占位符。

如果您对性能敏感并且正在使用大型表,则多个连接将比此子查询方法更好。

答案 2 :(得分:0)

您需要结合使用INNER JOINRIGHT JOIN

SELECT af.AvailableFieldID
from Config C 
    inner join Field F on F.configid = c.configid
    right join AvailableFields af on F.AvailableFieldID = af.AvailableFieldID
where f.AvailableFieldID is null

答案 3 :(得分:0)

使用

    SELECT AvailableFieldID FROM AvailableFields 
    WHERE AvailableFieldID  NOT IN ( 
           SELECT  AvailableFieldID from Field f INNER JOIN Config c ON f.ConfigID  = c.ConfigID INNER JOIN UserID u on u.UserID = c.UserID
           WHERE UserID = "Your condition")

我希望解决你的问题。

答案 4 :(得分:0)

回答您问题要求的简化版本:

        select af.AvailableFieldID 
        from AvailableFields af  -- all available fields
        left join (select distinct f.AvailableFieldID 
                   from Config c
                   join Fields f
                   on c.ConfigID = f.ConfigID
                   where c.UserID = @UserID) AS UserHas -- the fields the user has
        on af.AvailableFieldID = UserHas.AvailableFieldID
        where UserHas.AvailableFieldID is null -- a field match for the user isn't there

这也将返回不在Config中的AvailableFieldID。

你可能想要的版本b / c它可以是多用户:

    select u.UserID, af.AvailableFieldID 
    from Users u  -- all users
    cross join AvailableFields af  -- all fields
    left join (select distinct f.AvailableFieldID, c.UserID 
               from Config c
               join Fields f
               on c.ConfigID = f.ConfigID) AS UserHas -- the fields each user has
     on u.UserID = UserHas.UserID
        and af.AvailableFieldID = UserHas.AvailableFieldID
     where UserHas.AvailableFieldID is null -- a field match for the user isn't there
           and (@UserID is null or u.UserID = @UserID) -- option to limit it to one user