C'est un problème assez courant :générer une relation à la volée sans créer de table. Les solutions SQL pour ce problème sont assez maladroites. Un exemple utilisant une table dérivée :
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;
Mais cela ne s'adapte pas très bien, car vous pourriez avoir plusieurs valeurs au lieu de seulement six. Il peut devenir fastidieux de construire une longue liste avec un seul UNION
nécessaire par valeur.
Une autre solution consiste à conserver à portée de main un tableau à usage général de dix chiffres et à l'utiliser à plusieurs reprises à des fins multiples.
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;
Je montre la requête interne générant des valeurs de 0..99 même si ce n'est pas nécessaire dans ce cas. Mais vous pourriez avoir des valeurs supérieures à 10 dans votre liste. Le fait est qu'avec une table num
, vous pouvez générer de grands nombres sans avoir recours à de très longues chaînes avec un seul UNION
par valeur. En outre, vous pouvez spécifier la liste des valeurs souhaitées en un seul endroit, ce qui est plus pratique et lisible.