以下是该方案:
我有两张桌子:
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]
我想要返回的内容如下:
当我尝试此查询时:
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记录相关联的记录。
如何获得我追求的结果?
答案 0 :(得分: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'
答案 1 :(得分:0)
我在LEFT JOIN中使用gbn的例子,但这也等同于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'