3

この質問によると、Oracleで等価性チェックを実行する方法と、nullが等しいと見なされるようにしたいnullは次のようなものです

SELECT  COUNT(1)
  FROM    TableA
WHERE 
  wrap_up_cd = val
  AND ((brn_brand_id = filter) OR (brn_brand_id IS NULL AND filter IS NULL))

特に、このような場所がたくさんあり、場所が複数の列に適用されている場合、これは本当にコードを汚す可能性があります。これに代わるより良い方法はありますか?

4

3 に答える 3

5

まあ、これが良いかどうかはわかりませんが、指定された式がまたはUNKNOWN( )の場合に返される関数(句LNNVLでのみ使用できる)を使用する方が少し簡潔かもしれません。例えば...WHERETRUEFALSENULL

WITH T AS
(
    SELECT    1 AS X,    1 AS Y FROM DUAL UNION ALL
    SELECT    1 AS X,    2 AS Y FROM DUAL UNION ALL
    SELECT    1 AS X, NULL AS Y FROM DUAL UNION ALL
    SELECT NULL AS X,    1 AS Y FROM DUAL
)
SELECT
    *
FROM
    T
WHERE
    LNNVL(X <> Y);

... X=1およびY=2の行を除くすべてを返します。

于 2012-11-16T12:44:23.080 に答える
2

この関数を使用すると、 and ( and in the answer) が両方とも null のLNNVL場合、まだ問題があります。それは機能しますが、非効率的 (オプティマイザーによって理解されない) であり、データに表示できない値を見つける必要があります (オプティマイザーはそれができないことを認識している必要があります) 。 文字列の場合、列の最大数よりも多くの文字を含む値を選択できますが、それはダーティです。col1col2xynvl

それを行う真の効率的な方法は、(文書化されていない) function を使用することですSYS_OP_MAP_NONNULL()

このような:

where SYS_OP_MAP_NONNULL(col1) <> SYS_OP_MAP_NONNULL(col2)

SYS_OP_MAP_NONNULL(a)と同等ですnvl(a,'some internal value that cannot appear in the data but that is not null')

于 2015-03-08T16:25:03.577 に答える
2

NVL別の方法として、値が null の場合に返される関数と指定されたリテラルを使用できます。

-- both are not nulls
SQL> with t1(col1, col2) as(
  2    select 123, 123 from dual
  3  )
  4  select 1 res
  5    from t1
  6  where nvl(col1, -1) = nvl(col2, -1)
  7  ;

       RES
----------
         1

-- one of the values is null
SQL> with t1(col1, col2) as(
  2    select null, 123 from dual
  3  )
  4  select 1 res
  5    from t1
  6  where nvl(col1, -1) = nvl(col2, -1)
  7  ;

  no rows selected

 -- both values are nulls
 SQL> with t1(col1, col2) as(
  2    select null, null from dual
  3  )
  4  select 1 res
  5    from t1
  6  where nvl(col1, -1) = nvl(col2, -1)
  7  ;

       RES
----------
         1

もちろん、@Codo がコメントで指摘したように、上記のアプローチでは、列を比較するリテラルを選択する必要があります。比較する列が数値データ型 (たとえば) であり、任意の値を受け入れることができる場合、もちろん -1 を選択することはできません。その制限をなくすために、decode関数 (数値または文字データ型の場合) を使用できます。

 with t1(col1, col2) as(
  2    select null, null from dual
  3  )
  4  select 1 res
  5    from t1
  6  where decode(col1, col2, 'same', 'different') = 'same'
  7  ;

       RES
----------
         1
于 2012-11-16T07:23:25.190 に答える