OracleのIN句には、1,000項目までという制限があります。これをどうしても回避したいケースがあったので、回避方法を紹介します。
複合条件を使用する
SELECT * FROM table WHERE (アイテム, 1) IN (('AAA', 1), ('BBB', 1), ..., ('ZZZ', 1))
(‘値’, ダミーの値)とすることで上限を回避することが可能です。上記の場合、’AAA’や’BBB’が実際の条件として指定する値で1はダミーの値となります。
お手軽ですが、これにも落とし穴があり、65,535件より多くなるとエラー(ORA-00913: 値の個数が多すぎます)となってしまいます。
複数のIN句を使う
SELECT * FROM table WHERE column IN (val1, val2, ..., val1000)
OR column IN (val1001, val1002, ..., val2000);
1,000項目ごとに分割してORで繋ぎます。
UNION ALLを使用
SELECT * FROM table WHERE column IN (val1, val2, ..., val1000)
UNION ALL
SELECT * FROM table WHERE column IN (val1001, val1002, ..., val2000);
クエリを分割してUNION ALLで結合します。
EXISTS句を使用
SELECT * FROM main_table mt
WHERE EXISTS (
SELECT 1 FROM other_table ot
WHERE mt.A = ot.valA AND mt.B = ot.valB
);
条件に使用する値が別のテーブルに保存されている場合は、EXISTS句を使用することで、IN句の制限を回避することができます。特に、サブクエリを使用する場合に便利です。
他の方法に比べると処理も軽いので、使用できるのであればおすすめです。