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. 指定されたauthorization_keyに対してis_active
  2. external_id / API_User_idペアが存在する場合はそれと一致するSingle_Sign_On_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'
  • 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     
    (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

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'
于 2010-03-31T23:48:12.970 に答える