...row_number() over (partition by
...を使用してクエリの問題を解決しました。これは、結合でnull値の列を使用できない理由に関するより一般的な質問です。結合のためにnullをnullに等しくできないのはなぜですか?
結合のためにnullをnullに等しくできないのはなぜですか?
オラクルにそれをするように言ってください:
select *
from one t1
join two t2 on coalesce(t1.id, -1) = coalesce(t2.id, -1);
(標準SQLではt1.id is not distinct from t2.id
nullセーフな等価演算子を取得しますが、Oracleではサポートされていません)
ただし、これは、置換値(上記の例では-1)が実際にテーブルに表示されない場合にのみ機能します。数値のそのような「魔法の」値を見つけることは可能ですmightが文字値の場合は非常に困難になります(特に、Oracleは空の文字列をnull
としても扱うため)
加えて、id
列のインデックスは使用されません(ただし、couldcoalesce()
式で関数ベースのインデックスを定義します)。
魔法の値なしで、すべてのタイプで機能する別のオプション:
on t1.id = t2.id or (t1.id is null and t2.id is null)
しかし、本当の質問は:これは理にかなっていますか?
次のサンプルデータについて考えてみます。
表1
id
----
1
2
(null)
(null)
表2
id
----
1
2
(null)
(null)
(null)
結合でどのnull値の組み合わせを選択する必要がありますか?上記の例では、すべてのnull値のクロス結合のようなものになります。
T1_ID | T2_ID
-------+-------
1 | 1
2 | 2
(null) | (null)
(null) | (null)
(null) | (null)
(null) | (null)
(null) | (null)
(null) | (null)
または、INTERSECT
を等価演算子として使用して、2つのnullを互いに一致させることができます。
SELECT
*
FROM
t1
INNER JOIN t2
ON EXISTS (SELECT t1.ID FROM DUAL INTERSECT SELECT t2.ID FROM DUAL)
;
説明は このDBFiddleデモ を参照してください。
もちろん、これは一口に見えますが、実際には BriteSpongeの提案 より長くはありません。ただし、しゃれを許してしまうと、コメントの標準的な方法で前述したIS NOT DISTINCT FROM
演算子。Oracleではまだサポートされていません。
デコードを使用してnull値を結合できます。
_on decode(t1.id, t2.id, 1, 0) = 1
_
decode
はnullを等しいものとして扱うため、これは「マジック」番号なしで機能します。 2つの列は同じデータ型でなければなりません。
最も読みやすいコードにはなりませんが、おそらくt1.id = t2.id or (t1.id is null and t2.id is null)
より優れています。
完全を期すために、関数SYS_OP_MAP_NONNULL
は、12cのドキュメントに記載されているように、nullの値を比較するために安全に使用できるようになりました。これは、Oracleがランダムに削除してコードを壊すだけではないことを意味します。
SELECT *
FROM one t1
JOIN two t2
ON SYS_OP_MAP_NONNULL(t1.id) = SYS_OP_MAP_NONNULL(t2.id)
利点は、「マジック」ナンバーの問題に遭遇しないことです。
Oracleドキュメントのリファレンスは Basic Materialized Views-Choosing Indexes for Materialized Views にあります。
結合でnull値を使用できないのはなぜですか? Oracleでは、以下の両方がtrueと評価されません。
NULL = NULL
NULL <> NULL
そのため、IS NULL
/IS NOT NULL
null値を確認します。
これをテストするために、あなたは単に行うことができます:
SELECT * FROM table_name WHERE NULL = NULL
結合はブール条件を評価しており、異なる動作をするようにプログラムしていません。結合条件に大なり記号を入れて、他の条件を追加できます。ブール式として評価するだけです。
一貫性を保つために、結合ではnullをnullと同じにすることはできないと思います。比較演算子の通常の動作を無視します。