Este es un problema bastante común:generar una relación sobre la marcha sin crear una tabla. Las soluciones de SQL para este problema son bastante incómodas. Un ejemplo usando una tabla 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;
Pero esto no se escala muy bien, porque es posible que tenga muchos valores en lugar de solo seis. Puede volverse tedioso construir una lista larga con un UNION
necesario por valor.
Otra solución es tener a mano una tabla de propósito general de diez dígitos y usarla repetidamente para múltiples 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;
Muestro la consulta interna generando valores de 0 a 99 aunque esto no es necesario para este caso. Pero es posible que tenga valores superiores a 10 en su lista. El punto es que con una tabla num
, puede generar grandes números sin tener que recurrir a cadenas muy largas con un UNION
por valor. Además, puede especificar la lista de valores deseados en un solo lugar, lo que es más conveniente y legible.