static_rtti
static_rtti

Reputation: 56292

SQL: how do you look for missing ids?

Suppose I have a table with lots of rows identified by a unique ID. Now I have a (rather large) user-input list of ids (not a table) that I want to check are already in the database.

So I want to output the ids that are in my list, but not in the table. How do I do that with SQL?

EDIT: I know I can do that with a temporary table, but I'd really like to avoid that if possible.

EDIT: Same comment for using an external programming language.

Upvotes: 0

Views: 953

Answers (3)

vyegorov
vyegorov

Reputation: 22895

You haven't mentioned:

  • which RDBMS will be used;
  • what is the source of the IDs.

So I will consider PostgreSQL is used, and IDs to be checked are loaded into a (temporary) table.

Consider the following:

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);

You can get your results like this:

SELECT * FROM temp_table WHERE NOT EXISTS (
    SELECT id FROM test WHERE id = temp_table.id);

or

SELECT * FROM temp_table WHERE id NOT IN (SELECT id FROM test);

or

SELECT * FROM temp_table LEFT JOIN test USING (id) WHERE test.id IS NULL;

You can pick any option, depending on your volumes you may have different performance.

Just a note: some RDBMS may have limitation on the number of expressions specified literally inside IN() construct, keep this in mind (I hit this several times with ORACLE).

EDIT: In order to match constraints of no temp tables and no external languages you can use the following construct:

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;

Unfortunately, you'll have to generate lot's of SELECT x UNION ALL entries to make a single-column and many-rows table here. I use UNION ALL to avoid unnecessary sorting step.

Upvotes: 1

k_rus
k_rus

Reputation: 3219

It is hardly possible to make a single pure and general SQL query for your task, since it requires to work with a list (which is not a relational concept and standard set of list operations is too limited). For some DBMSs it is possible to write a single SQL query, but it will utilize SQL dialect of the DBMS and will be specific to the DBMS.

Upvotes: 1

Marco
Marco

Reputation: 57583

Try with this:

SELECT t1.id FROM your_list t1
LEFT JOIN your_table t2
  ON t1.id = t2.id
WHERE t2.id IS NULL

Upvotes: 5

Related Questions