2010-12-15 6 views
15

Est-il possible d'inclure dans une clause IN plusieurs champs? Quelque chose comme ce qui suit:Clause SQL Server - IN avec plusieurs champs

select * from user 
where code, userType in (select code, userType from userType) 

J'utilise ms sql server 2008


Je sais que cela peut être réalisé avec des jointures et EXISTE, je voulais juste savoir si elle pourrait juste être fait avec la clause IN.

+4

Le fait que vous attendez * deux colonnes * d'une table à être « IN » un La deuxième table suggère une conception de schéma nécessitant une normalisation supplémentaire. –

Répondre

14

Pas la façon dont vous avez posté. Vous ne pouvez renvoyer qu'un seul champ ou type pour que IN fonctionne.

De MSDN (IN):

test_expression [ NOT ] IN 
    (subquery | expression [ ,...n ] 
    ) 

subquery - Is a subquery that has a result set of one column. 
      This column must have the same data type as test_expression. 

expression[ ,... n ] - Is a list of expressions to test for a match. 
         All expressions must be of the same type as 
         test_expression. 

Au lieu de IN, vous pouvez utiliser un JOIN en utilisant les deux champs:

SELECT U.* 
FROM user U 
    INNER JOIN userType UT 
    ON U.code = UT.code 
    AND U.userType = UT.userType 
+0

Yeap, je me doutais qu'il était impossible – opensas

+0

http://social.msdn.microsoft.com/forums/en-US/transactsql/thread/4e058e95-9d7c-4baa-a73e-3c849b4c6463
supprimer de test1 où non eXISTE (sélectionnez 0 de test2 où test1.col1 = test2.col1 et test1.col2 = test2.col2) – Vijay

+0

@Vijay - Qu'est-ce que vous essayez de dire ici? – Oded

0

Que diriez-vous plutôt:

SELECT user.* FROM user JOIN userType on user.code = userType.code AND user.userType = userType.userType 
9

Vous pouvez utiliser un formulaire comme celui-ci:

select * from user u 
where exists (select 1 from userType ut 
       where u.code = ut.code 
       and u.userType = ut.userType) 
+0

oui, je le fais habituellement de cette façon, juste en essayant d'éviter l'existence ... – opensas

+1

Eh bien, vous devrez probablement utiliser soit «EXISTS» ou «JOIN» pour accomplir cela. – cdhowie

+0

oui, cdhowie, c'est ce que ma question était sur ... – opensas

-2

Je ne pense pas que cette requête est tout à fait portable, il serait plus sûr d'utiliser quelque chose comme

select * from user 
where code in (select code from userType) and userType in (select userType from userType) 
+1

mmmm ... Je suppose que ce n'est pas la même chose, je suis à la recherche d'un enregistrement avec le même code et userType ... – opensas

+1

Cela ne fonctionnera pas. Vous pourriez avoir un enregistrement qui correspond à votre 'code' et un autre enregistrement qui correspond à votre' userType'. – Andrew

0

Vous pouvez utiliser les jointures

SELECT * FROM user U 
INNER JOIN userType UT on U.code = UT.code 
AND U.userType = UT.userType 
+0

Je pense que les deux requêtes ne sont pas équivalentes, la deuxième requête peut correspondre à deux enregistrements différents de la table userType – opensas

+0

Hmmm .. vous avez raison. Mais cela pourrait être l'un ou l'autre, cela dépend de ce qu'il veut. Comme il a accepté la réponse avec des jointures, ça doit être ça. Edited ma réponse. Merci. – pavanred

-3
select * from user 
where (code, userType) in (select code, userType from userType); 
+4

Cela fonctionne dans Oracle, mais pas SQLS –

4

Seulement avec quelque chose d'horrible, comme

select * from user 
where (code + userType) in (select code + userType from userType) 

Ensuite, vous devez gérer les NULL et concaténer les nombres plutôt que de les ajouter, et le cast, et un code de 12 et un usertype de 3 vs un code de 1 et un usertype de 23, et ...

ya aller: une solution qui n'utilise pas de jointures ou existe .. et un tas de raisons pour lesquelles vous ne devriez pas l'utiliser;)

+0

J'ai utilisé cela, mais cela ne fonctionne que si les champs sont les deux chaînes. Aussi, je recommande d'utiliser un caractère entre les deux champs comme '|' c'est-à-dire 'où (code + '|' + userType) dans (sélectionnez le code + '|' + userType de userType)'. Mais je suis d'accord que ce n'est pas une bonne solution. – Andrew

0

Je devais faire quelque chose de très similaire mais EXISTS ne fonctionnait pas dans ma situation. Voici ce qui a fonctionné pour moi:

UPDATE tempFinalTbl 
SET BillStatus = 'Non-Compliant' 
WHERE ENTCustomerNo IN (SELECT DISTINCT CustNmbr 
      FROM tempDetailTbl dtl 
      WHERE dtl.[Billing Status] = 'NEEDS FURTHER REVIEW' 
       AND dtl.CustNmbr = ENTCustomerNo 
       AND dtl.[Service] = [Service]) 
    AND [Service] IN (SELECT DISTINCT [Service] 
      FROM tempDetailTbl dtl 
      WHERE dtl.[Billing Status] = 'NEEDS FURTHER REVIEW' 
       AND dtl.CustNmbr = ENTCustomerNo 
       AND dtl.[Service] = [Service]) 

EDIT: Maintenant que je regarde, ce qui est très proche de @ v1v3kn de réponse