LNNVL正当化


12

LNNVLは、Oracleの組み込み関数であり、FALSEまたはUNKNOWNと評価される条件に対してTRUEを返し、TRUEと評価される条件に対してFALSEを返します。私の質問は、単にNULL値を処理するのではなく、真理条件の反対を返すことの利点は何でしょうか?

たとえば、ヌルを含む可能性のあるStartCommission列とCurrentCommission列を持つEmpテーブルがあるとします。次の例では、値がnullでない行のみが返されます。

SELECT * FROM Emp WHERE StartCommission = CurrentCommission;

いずれかのコミッションがnullである行を含めたい場合、次のようなことができます。

SELECT * FROM Emp WHERE StartCommission = CurrentCommission 
OR StartCommission IS NULL OR CurrentCommission IS NULL;

この構文を短縮する関数が存在するように思われますが、LNNVLを使用すると、すべての等しくないレコードとNULLを持つすべてのレコードが返されます。

SELECT * FROM Emp WHERE LNNVL(StartCommission = CurrentCommission);

これにNOTを追加すると、nullのない行のみが返されます。この場合に望ましい機能は、真の条件を真、偽の条件を偽に保ち、未知の条件を真と評価することです。ここで低ユースケースを実際に作成しましたか?不明をtrueに、trueをfalseに、falseをtrueにしたいというのは本当ですか?

create table emp (StartCommission Number(3,2), CurrentCommission Number(3,2));
insert into emp values (null,null);
insert into emp values (null,.1);
insert into emp values (.2,null);
insert into emp values (.3,.4);

今日、私はLNNVLに会いましたが、「真実の反対を返すことの利点は何か」についてもこの部分を見つけ、理解しようとしています。ただし、LNNVLを例示するために使用するステートメントでは、等しくない演算子を使用する必要があります。SELECT * FROM Emp WHERE LNNVL(StartCommission <> CurrentCommission); つまり、ORを使用したステートメントと同じ結果を返します。つまり、条件を使用しており、NULL値を持つ行も含める場合は、条件の否定をLNNVLに渡す必要があります。
あなただけ

別の簡単な例。実際に20%未満のコミッションを受け取った従業員のみ:SELECT * FROM従業員WHERE Commission_pct <.2; コミッションをまったく受け取らない従業員も含めるには、次のようにします。SELECT * FROM従業員WHERE LNNVL(commission_pct> = .2);
あなただけ

@OnlyYou-LNNVLを同じように動作させるには、条件が<>でなければならないというのは正しいです。関数が=記号を使用して同じ結果を返す場合、より意味があるので、私はそれをより多く残しました。基本的に、この関数は2つのアクションを実行しています。1。Null包含、2。ブールトグル。前者は理にかなっていますが、後者は望ましい条件の反対を必要とするものを混乱させるようです。つまり、=は<>が必要、<は> =が必要など
リーリッフェル

回答:


6

これは、との奇妙な関数である奇妙な歴史 -しかし、そのようにあるNVL2奇妙。lnnvl基本的にはis not true演算子です-間違いなくcanのように使いこなすnvl2ことができますが、使用するたびに関数を調べて正確に何をするかを思い出さなければならないとき、あなたはそれに固執するのが最善かどうか疑問に思われますnvlcoalescedecodenullif一緒にcase、より直感的表現、


NVL2が変だとは思いませんが、それを頻繁に使用し、LNNVLを使用したことはありません。
リーリフェル

@Leigh-変にならない程度に頻繁に使用する必要があると思います:) nullif「ゼロ除算」= nullにするのに非常に役立つことがわかったまで、私は使用しませんでした。あなたは本当にnvl2(a、c、b)をdecode(a、null、b、c)よりもはるかに優れていると思いますか?
ジャックは、topanswers.xyz

4

このように言えば、DBAおよびPL / SQLプログラマーとしての数年間でLNNVLを使用したことがありません。私はときどきNVL2を使用しました(どちらの側が本当で、どちらの側がそうでないかを常に調べなければなりませんでした)。その時点では、読みやすさの観点から、NVL、DECODE、CASEなどを使用する方が良いようです。

あるいは、OracleがNULLと算術を処理する方法に優れたハンドルを持っていると仮定すると、これは機能しますが、この時点で、元のクエリを読みやすくするために使用することもできます(実行プランもより厳しいヒットを取るかもしれません):

/* Return all rows where StartCommission is the same
 * as Current Commission, or those rows who have a
 * NULL in either (including both)
 */

SELECT *
  FROM Emp
 WHERE StartCommission = CurrentCommission
    OR StartCommission + CurrentCommission IS NULL

-- NULL + NULL, or NULL + Number is always NULL; hence return either
-- those records that are equal, or have a combined total of NULL
-- (either or both fields will be NULL).

という意味StartCommission<>CurrentCommission OR StartCommission + CurrentCommission IS NULLですか?
ジャックはtopanswers.xyzを試す11

@JackPDouglas-=として理にかなっています。
リーリッフェル

興味深いバリエーション。あなたの結論に同意します。
リーリッフェル

@Leigh-あなたが望む関数の代替物であり、の代替物ではないようlnnvlです。
ジャックは、topanswers.xyz

@JackPDouglas-私は理解しており、それがKerriが意図したものだと思います。
リーRiffel
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.