2009-12-04 3 views
4

(Je ne pense pas que j'ai intitulé cette question correctement - mais je ne sais pas comment le décrire)T-SQL - Comment écrire requête pour obtenir des enregistrements qui correspondent à tous les enregistrements dans un plusieurs à rejoindre

Voici ce que j'essaie de faire:

Disons que j'ai une table Person qui a un champ PersonID. Et disons qu'une personne peut appartenir à plusieurs groupes. Il existe donc une table Group avec un champ GroupID et une table GroupMembership qui est une jointure many-to-many entre les deux tables et la table GroupMembership a un champ PersonID et un champ GroupID. Jusqu'à présent, il est un simple à plusieurs rejoindre.

Étant donné une liste d'ID de groupe, j'aimerais pouvoir écrire une requête qui renvoie toutes les personnes qui appartiennent à TOUS ces groupes (pas l'un de ces groupes). Et la requête devrait être capable de gérer n'importe quel nombre de GroupID. Je voudrais éviter le SQL dynamique.

Existe-t-il une façon simple de faire cela qui me manque? Merci, Corey

Répondre

6
select person_id, count(*) from groupmembership 
where group_id in ([your list of group ids]) 
group by person_id 
having count(*) = [size of your list of group ids] 

Modifié: merci dotjoe!

+0

Je ne pense pas que ce soit ce qu'il veut –

+1

ayant count (*) = @count_of_your_list_of_group_ids – dotjoe

0

Fondamentalement, vous êtes à la recherche de personnes pour lesquelles il n'y a pas de groupe, il n'est pas membre, si

select * 
from Person p 
where not exists (
    select 1 
    from Group g 
    where not exists (
     select 1 
     from GroupMembership gm 
     where gm.PersonID = p.ID 
     and gm.GroupID = g.ID 
    ) 
) 
+0

Pas exactement. Je cherche une personne qui est un membre de tous les groupes dans une liste donnée de groupes. –

0

Vous n'allez essentiellement pas éviter le SQL "dynamique" dans le sens d'une génération dynamique de la requête au moment de la requête. Il n'y a aucun moyen de remettre une liste en SQL (bien, il y a des variables de table, mais les obtenir dans le système à partir de C# est soit impossible (2005 & ci-dessous) ou ennuyeux (2008)). Une façon de le faire avec plusieurs requêtes est d'insérer votre liste dans une table de travail (probablement une table à clé de processus) et de se joindre à cette table. La seule autre option serait d'utiliser une requête dynamique telle que celles spécifiées par Jonathan et hongliang.

+0

Je suppose que par SQL dynamique, je voulais dire un SP qui concatène une grosse chaîne SQL ensemble, puis l'exécute. Je sais que cela ne fonctionne pas très bien, alors j'essaie d'éviter cela. L'exemple de Jonathan ci-dessus semble être ce que je cherche. –

+0

@Aequitarum a raison, il existe plusieurs façons de diviser un 'varchar' et de manipuler la liste en tant que table. –

+0

Aucun doute. Je ne suis pas sûr d'utiliser une table de travail est pire une option, cependant. –

Questions connexes