一意の ID で識別される多数の行を含むテーブルがあるとします。これで、チェックしたい ID (テーブルではない) の (かなり大きな) ユーザー入力リストが既にデータベースに存在します。
したがって、リストにはあるがテーブルにはないIDを出力したいと思います。SQLでそれを行うにはどうすればよいですか?
編集:一時テーブルでそれができることは知っていますが、可能であればそれを避けたいと思います。
編集: 外部プログラミング言語を使用するための同じコメント。
これで試してください:
SELECT t1.id FROM your_list t1
LEFT JOIN your_table t2
ON t1.id = t2.id
WHERE t2.id IS NULL
あなたは言及していません:
そこで、PostgreSQL を使用し、チェックする ID を (一時) テーブルにロードすることを検討します。
次の点を考慮してください。
CREATE TABLE test (id integer, value char(1));
INSERT INTO test VALUES (1,'1'), (2,'2'), (3,'3');
CREATE TABLE temp_table (id integer);
INSERT INTO temp_table VALUES (1),(5),(10);
次のように結果を取得できます。
SELECT * FROM temp_table WHERE NOT EXISTS (
SELECT id FROM test WHERE id = temp_table.id);
また
SELECT * FROM temp_table WHERE id NOT IN (SELECT id FROM test);
また
SELECT * FROM temp_table LEFT JOIN test USING (id) WHERE test.id IS NULL;
パフォーマンスが異なる可能性があるボリュームに応じて、任意のオプションを選択できます。
注意: 一部の RDBMSIN()
では、コンストラクト内で文字通り指定された式の数に制限がある場合があります。これを覚えておいてください (私は ORACLE でこれを数回ヒットしました)。
編集:一時テーブルも外部言語もないという制約に一致させるために、次の構成を使用できます。
SELECT DISTINCT b.id
FROM test a RIGHT JOIN (
SELECT 1 id UNION ALL
SELECT 5 UNION ALL
SELECT 10) b ON a.id=b.id
WHERE a.id IS NULL;
残念ながら、SELECT x UNION ALL
ここで単一列と複数行のテーブルを作成するには、多数のエントリを生成する必要があります。UNION ALL
不必要なソート手順を避けるために使用します。
リストを操作する必要があるため、単一の純粋で一般的な SQL クエリを作成することはほとんど不可能です (これはリレーショナルの概念ではなく、リスト操作の標準的なセットはあまりにも限られています)。一部の DBMS では、単一の SQL クエリを作成できますが、これは DBMS の SQL 方言を利用し、DBMS に固有のものになります。