0

这是场景:

我有 2 张桌子:

CREATE TABLE dbo.API_User
    (
    id int NOT NULL,
    name nvarchar(255) NOT NULL,
    authorization_key varchar(255) NOT NULL,
    is_active bit NOT NULL
    )  ON [PRIMARY]

CREATE TABLE dbo.Single_Sign_On_User
    (
    id int NOT NULL IDENTITY (1, 1),
    API_User_id int NOT NULL,
    external_id varchar(255) NOT NULL,
    user_id int NULL
    )  ON [PRIMARY]

我要返回的是以下内容:

  1. is_active 对于给定的授权密钥
  2. Single_Sign_On_User.id 匹配 external_id/API_User_id 对(如果存在)或 NULL 如果不存在这样的对

当我尝试这个查询时:

SELECT Single_Sign_On_User.id, API_User.is_active
FROM API_User LEFT OUTER JOIN
    Single_Sign_On_User ON Single_Sign_On_User.API_User_id = API_User.id
WHERE     
    Single_Sign_On_User.external_id = 'test_ext_id' AND 
    API_User.authorization_key = 'test'

其中“test”API_User 记录存在但“test_ext_id”记录不存在,并且在任何一个表中都没有其他值,我没有返回任何记录。

当我使用:

SELECT Single_Sign_On_User.id, API_User.is_active
FROM API_User LEFT OUTER JOIN
    Single_Sign_On_User ON Single_Sign_On_User.API_User_id = API_User.id
WHERE     
    API_User.authorization_key = 'test'

我得到了我期望的结果(NULL,1),但是该查询不允许我找到“test_ext_id”记录(如果存在),但会给我与“test”API_User 记录关联的所有记录。

我怎样才能得到我想要的结果?

4

2 回答 2

3

过滤“外部”表”会将联接更改为 INNER。

4个选项,其中前2个最好

  • 派生表

在派生表内过滤

SELECT SSOU.id, API_User.is_active
FROM
    API_User
    LEFT OUTER JOIN
    (
    SELECT id FROM Single_Sign_On_User WHERE external_id = 'test_ext_id'
    ) SSOU  ON SSOU.API_User_id = API_User.id
WHERE     
    API_User.authorization_key = 'test'
  • SQL Server 2005+ 的 CTE(代替派生表)

  • 在 JOIN 中过滤

因此;

SELECT Single_Sign_On_User.id, API_User.is_active
FROM API_User LEFT OUTER JOIN
    Single_Sign_On_User ON Single_Sign_On_User.API_User_id = API_User.id

    AND Single_Sign_On_User.external_id = 'test_ext_id'

WHERE     
    API_User.authorization_key = 'test'
  • 或子句

因此:

SELECT Single_Sign_On_User.id, API_User.is_active
FROM API_User LEFT OUTER JOIN
    Single_Sign_On_User ON Single_Sign_On_User.API_User_id = API_User.id
WHERE     
    (Single_Sign_On_User.external_id = 'test_ext_id' OR Single_Sign_On_User.external_id IS NULL)
    AND
    API_User.authorization_key = 'test'
于 2010-03-31T21:13:44.560 回答
0

我将 gbn 的示例与 LEFT JOIN 中的条件一起使用,但这也等同于 OR 并且有时在代码生成中可能会更好(没有讨厌的括号来跟踪 OR):

SELECT Single_Sign_On_User.id
       ,API_User.is_active
FROM API_User
LEFT OUTER JOIN Single_Sign_On_User
    ON Single_Sign_On_User.API_User_id = API_User.id
WHERE COALESCE(Single_Sign_On_User.external_id, 'test_ext_id') = 'test_ext_id'
    AND API_User.authorization_key = 'test'
于 2010-03-31T23:48:12.970 回答