4

申し訳ありませんが、これをどのように表現すればよいかわかりませんでしたが、where 句に次のように記述しています。

person_id not in (
    SELECT distinct person_id
    FROM protocol_application_log_devl pal
    WHERE pal.set_id = @set_id
)

サブクエリが結果を返さない場合、選択全体が何も返されません。これを回避するためperson_idに、サブクエリをに置き換えましたisnull(person_id, '00000000-0000-0000-0000-000000000000')

うまくいくようですが、これを解決するより良い方法はありますか?

4

4 に答える 4

2

私はTimの答えを実際に正しいものとして支持していますが(NOT INはここでは適切ではありません)、これはIN / NOT INドキュメントに記載されている興味深いケースです:

注意: IN または NOT IN を使用して test_expression と比較されるサブクエリまたは式によって返される null 値は、UNKNOWN を返します。IN または NOT IN と一緒に null 値を使用すると、予期しない結果が生じる可能性があります1

isnullこれが、 が問題を「修正」する理由です。このような NULL 値をマスクし、予期しない動作を回避します。それを念頭に置いて、次のアプローチも機能します (ただし、最初から NOT IN を使用しないことについてのアドバイスに注意してください)。

person_id not in (
  SELECT distinct person_id
  FROM protocol_application_log_devl pal
  WHERE pal.set_id = @set_id
    AND person_id NOT NULL    -- guard here
)

ただし、NULL の person_id は疑わしいものであり、他の問題を示している可能性があります..

1プルーフプディングは次のとおりです。

select case when 1 not in (2)       then 1 else 0 end as r1,
       case when 1 not in (2, NULL) then 1 else 0 end as r2
-- r1: 1, r2: 0
于 2013-10-31T23:13:39.533 に答える
0

これはうまくいくはずです:

nvl(person_id, '') not in (
    SELECT distinct person_id
    FROM protocol_application_log_devl pal
    WHERE pal.set_id = @set_id
)
于 2020-08-06T15:17:25.473 に答える