2017-07-19 2 views
0

いくつかの条件に基づいて結果セットから除外したい行のリストがあります。現在のところ、それは私のクエリで次のようになります。Postgres:CASE文の否定条件

SELECT ... 
    , CASE WHEN condition1 THEN 'Exclusion Reason 1' 
     WHEN condition2 THEN 'Exclusion Reason 2' 
     ... 
     ELSE '' 
    END AS exclusion_reason 

問題:それはいないようです

WHERE col1 = 'x' OR col1 ~~ '%y%' AND col2 = 'z' ... 

は、今私は、特定の行が除外された理由を文書化、新しい列を導入したいです

SELECT ... 
    , CASE WHEN condition1 THEN 'Reason 1' 
     WHEN condition2 THEN 'Reason 2' 
     WHEN NOT (col1 = 'x' OR col1 ~~ '%y%' AND col2 = 'z'...) THEN 'Reason 3' 
     ELSE '' 
    END AS exclusion_reason 

それは必要がありますがそれは、Reason 3で任意の行を返さない:私は否定を使用するように動作します。 NOTを省略すると、行のサブセットをマーク:

SELECT ... 
    , CASE WHEN condition1 THEN 'Reason 1' 
     WHEN condition2 THEN 'Reason 2' 
     WHEN (col1 = 'x' OR col1 ~~ '%y%' AND col2 = 'z'...) THEN 'Not Reason 3' 
     ELSE '' 
    END AS exclusion_reason 

なぜ期待通りに否定は動作しないと、ここで使用する正しい構文は何であるのか?

+0

[documentation](https://www.postgresql.org/docs/9.1/static/sql-expressions.html#SYNTAX-EXPRESS-EVAL)のコメントでは、明示的に次のように述べています。*「評価の順序特に、演算子や関数の入力は、必ずしも左から右、または他の固定された順序で評価されるわけではありません。 "*、'() 'で囲む方が安全です。正確な部分は必要ありません一致。与えられた例 '((col1 = 'x' OR col1 ~~ '%y%')AND col2 ...)'などで –

答えて

1

私は理由がNULL値であるので、このような何かということを推測するつもりです:条件で

WHEN NOT (col1 = 'x' OR col1 ~~ '%y%' AND col2 = 'z'...) OR col1 IS NULL THEN 'Reason 3' 

NULL値がNULLを返します。 NOT NULLはまだNULLです。これはfalseとして処理されます。