OÙ col1,col2 EN (...) [sous-requête SQL à l'aide de clé primaire composite]
Donné un tableau foo
avec une clé primaire composite (a,b)
, est-il légal de syntaxe pour écrire une requête telle que:
SELECT ... FROM foo WHERE a,b IN (SELECT ...many tuples of a/b values...);
UPDATE foo SET ... WHERE a,b IN (SELECT ...many tuples of a/b values...);
Si ce n'est pas possible, et on ne pouvait pas modifier le schéma, comment pouvez-vous effectuer l'équivalent de ce qui précède?
Je vais aussi mettre les termes "composé de clé primaire", "sélectionner", "sous-select" et "sous-requête" ici pour les résultats de recherche sur ces alias.
Modifier: je suis intéressé par les réponses pour le standard SQL ainsi que ceux qui pourraient travailler avec PostgreSQL et SQLite 3.
Vous devez vous connecter pour publier un commentaire.
Remplacer le
select 1 from bar
avec votreselect ... many tuples of a/b values ...
.Ou de créer une table temporaire de votre
select ... many tuples of a/b values ...
et l'utiliser à la place debar
..Votre syntaxe est très proche du Standard SQL!
Ce qui suit est valable COMPLÈTE de SQL-92 (comme l'a confirmé le Mimer SQL-92 Validateur)
Bien sûr, pas tous les SQL produit prend en charge complète de SQL-92 (la honte!) Si quelqu'un souhaite voir cette syntaxe pris en charge dans Microsoft SQL Server, ils peuvent voter pour elle ici.
Un autre SQL-92 construire que ce qui est largement pris en charge (par exemple par Microsoft SQL Server et Oracle) est
INTERSECT
par exempleNoter que ces constructions gérer correctement la
NULL
valeur, contrairement à d'autres suggestions ici, par exemple, ceux qui utilisentEXISTS (<equality predicates>)
, valeurs concaténées, etc.SELECT * FROM foo WHERE (a,b) IN ((1,2),(3,4))
INTERSECT
estEXCEPT
Vous avez fait une très petite erreur.
Vous devez mettre a,b entre parenthèses.
Qui fonctionne!
La syntaxe vous l'avez suggéré, n'est pas valide SQL. Une solution EXISTE devraient travailler dans tous raisonnablement compatible SQL RDBMSes:
Être conscient que ce n'est souvent pas particulièrement performant.
Que ce que vous recherchez?
UPDATE
sur SQLite3, qui ne prend pas en charge les jointures dans la mise à JOUR les requêtes. J'essaie en partie à savoir si le noyau multi-touches EN est légal (je viens de lire qu'il n'est pas dans SQLite), mais aussi pour aider les répondre à cette question.Avec la concaténation, cela fonctionne avec PostgreSQL:
Si vous avez besoin d'une solution qui ne nécessite pas les n-uplets de valeurs déjà existantes dans une table, vous pouvez concaténer le tableau des valeurs et des éléments de votre liste, puis utilisez le 'DANS' la commande.
Dans postgres ce serait ressembler à ceci:
SELECT * FROM foo WHERE a || '_' || b in ('Hi_there', 'Me_here', 'Test_test');
Tandis que dans SQL j'imagine qu'il pourrait ressembler à quelque chose comme ceci:
SELECT * FROM foo WHERE CONCAT(a, "_", b) in ('Hi_there', 'Me_here', 'Test_test');
JOINS
etINTERSECTS
fonctionner comme un substitut pourIN
, mais ils ne sont pas si évidentes comme un substitut pourNOT IN
, par exemple: l'insertion de lignes deTableA
enTableB
où ils n'existent pas déjà dansTableB
où laPK
sur les deux tableaux est un composite.Je suis actuellement en utilisant la méthode de concaténation ci-dessus dans SQL Server, mais elle n'est pas très élégant.
MERGE..USING..WHEN NOT MATCHED THEN INSERT...
Firebird utilise cette formule de concaténation: