2009-06-05 5 views
2

Dans certains dialectes SQL, vous pouvez dire (quelque chose comme):Existe-t-il une implémentation de cette syntaxe de requête dans TSQL?

SELECT * FROM SomeTable WHERE (val1,val2) IN 
    (SELECT val1,val2 FROM SomeOtherTable) 

Mais je ne sais pas comment faire dans le TSQL (SQL Server 2k) J'utilise.

Je connais (et j'utilise pour l'instant) des solutions de contournement telles que l'utilisation de jointures ou de valeurs concaténées, mais y a-t-il une syntaxe dans TSQL que je néglige de faire? MISE À JOUR: Ceci est une syntaxe SQL-99 valide, c'est pourquoi je considère une jointure une solution de contournement, même si ce serait plus performant. Ma question est peut-être meilleure:

Existe-t-il une implémentation de cette syntaxe dans TSQL?

UPDATE2: Je viens de tester cette syntaxe de Mysql et ça marche bien.

+0

Je n'appellerais pas l'utilisation de jointures _workaround_. Je ne suis pas un expert SQL, mais je suis à peu près certain que JOIN va être beaucoup plus rapide que l'utilisation de IN. – Rake36

+0

@Rake: Dépend de la clause IN. Dans ce cas, les scinder en sous-sélections sera (et en utilisant un filtrage par ligne) plus lent qu'une jointure. – Eric

+2

@Rake: SQL Server peut optimiser. Il existe un algorithme spécial SEMI JOIN spécialement conçu pour de tels cas. C'est plus rapide qu'un JOIN avec DISTINCT ultérieur. – Quassnoi

Répondre

10
SELECT * 
FROM SomeTable st 
WHERE EXISTS 
     (
     SELECT 1 
     FROM SomeOtherTable sot 
     WHERE sot.val1 = st.val1 
       AND sot.val2 = st.val2 
     ) 

Ceci est en fait ce qu'est une construction IN est optimisé pour toute méthode SEMI JOIN.

Quant à votre question,

Y at-il une implémentation de cette syntaxe dans T-SQL?

la réponse est pas

Comme documentation dit:

... subquery qui a un jeu de résultats de une colonne. Cette colonne doit avoir le même type de données que test_expression.

+0

+1, bon substitut, mais toujours pas de réponse à la question – Peter

+0

tx. – Peter

+2

@Peter: comment avez-vous fait un si court commentaire? – Quassnoi

1

Rejoindre serait le chemin à parcourir. IN

0

IN ne fonctionne que sur les réseaux à une seule colonne. Puisque vous avez explicitement déclaré que vous voulez faire une clause IN:

SELECT * FROM SomeTable 
WHERE val1 IN (SELECT val1 FROM SomeOtherTable WHERE val2 = SomeTable.val2) 
AND val2 IN (SELECT val2 FROM SomeOtherTable WHERE val1 = SomeTable.val1) 

Vérifiez la documentation sur elle. Puisqu'il existe une clause where qui dépend de chaque ligne (par exemple, -WERE SomeOtherTable.ID = SomeTable.MyOtherID), cela améliore les performances et une jointure est absolument la solution.

+0

Ce n'est pas la même chose, car les valeurs val1 et val2 correspondantes peuvent provenir de lignes différentes dans SomeOtherTable –

+0

Cela ne fonctionnerait pas nécessairement, n'est-ce pas? Cela pourrait vous donner une correspondance s'il y a une ligne dans SomeOtherTable qui a val1 correspondant mais pas val2 (et vice versa) tant qu'il y avait une autre ligne qui pouvait correspondre à l'autre valeur. – TheTXI

+0

* secoue le poing en colère contre Joel * – TheTXI

4

Il n'y a pas de mise en œuvre du serveur sql de cette syntaxe. Vous aurez à faire quelque chose comme ceci:

SELECT st.* 
FROM SomeTable st 
    INNER JOIN 
    (
    SELECT val1, val2 
    FROM SomeOtherTable 
    GROUP BY val1, val2 
) sot ON sot.val1= st.val1 AND sot.val2 = st.val2 
+0

En aucune version unique? Pas même en 2008? – Peter

+0

Non, ce n'est pas en 2008. –

0
Select SomeTable.* 
FROM SomeTable, SomeOtherTable 
WHERE SomeTable.Val1 = SomeOtherTable.Val1 
    And SomeTable.Val2 = SoemeOtherTable.Val2 

Vous ne devriez pas considérer cela comme une "solution". C'est la manière la plus basique et standard d'accomplir ce que vous voulez accomplir. Editer: Ce n'est peut-être pas votre syntaxe standard "JOIN", mais c'est une habitude.

+1

Cela pourrait causer des résultats en double si SomeOtherTable a plus d'un enregistrement avec les colonnes val1 et val2 qui correspondent à un enregistrement de SomeTable. –

+1

En outre, je veux vraiment downvote la syntaxe "Table1, Table2". –

+0

Bon point Joel. N'a pas pensé à des résultats en double étant un effet secondaire inutile. – TheTXI

Questions connexes