Esse é um problema bastante comum:gerar uma relação em tempo real sem criar uma tabela. As soluções SQL para este problema são bastante estranhas. Um exemplo usando uma tabela derivada:
SELECT n.id
FROM
(SELECT 2 AS id
UNION SELECT 3
UNION SELECT 4
UNION SELECT 5
UNION SELECT 6
UNION SELECT 7) AS n
LEFT OUTER JOIN foos USING (id)
WHERE foos.id IS NULL;
Mas isso não escala muito bem, porque você pode ter muitos valores em vez de apenas seis. Pode se tornar cansativo construir uma longa lista com um
UNION
necessário por valor. Outra solução é manter uma tabela de uso geral de dez dígitos à mão e usá-la repetidamente para vários propósitos.
CREATE TABLE num (i int);
INSERT INTO num (i) VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9);
SELECT n.id
FROM
(SELECT n1.i + n10.i*10 AS id
FROM num AS n1 CROSS JOIN num AS n10
WHERE n1.i + n10.i*10 IN (2, 3, 4, 5, 6, 7)) AS n
LEFT OUTER JOIN foos USING (id)
WHERE foos.id IS NULL;
Eu mostro a consulta interna gerando valores de 0..99 mesmo que isso não seja necessário para este caso. Mas você pode ter valores maiores que 10 em sua lista. O ponto é que com uma tabela
num
, você pode gerar grandes números sem ter que recorrer a cadeias muito longas com um UNION
por valor. Além disso, você pode especificar a lista de valores desejados em um só lugar, o que é mais conveniente e legível.