2009-01-06 8 views
10

Wow, il est difficile de trouver une explication simple à ce sujet. Une simple relation plusieurs-à-plusieurs.Exemples de requêtes dans une relation plusieurs-à-plusieurs

Trois tables, tableA, tableB et une table de jonctionA_B.

Je sais comment mettre en place la relation, avec les touches et tout, mais je suis un peu confus quand vient le temps d'effectuer INSERT, UPDATE et DELETE requêtes ....

En gros, ce que je cherche est un exemple qui montre:

  1. Comment obtenir tous les enregistrements de TableA, basé sur un ID dans TableB

  2. Comment obtenir tous les enregistrements TableB, basé sur un ID dans TableA

3 Comment insérer dans les deux TableA ou TableB, puis prendre la INSERT appropriée dans la table de jonction pour établir la connexion ..

Je ne suis pas à la recherche d'une solution à un projet spécifique, à quelques exemples généraux qui peuvent être appliqués. Peut-être que vous avez quelque chose qui traîne?

Répondre

6

La première chose que je voudrais faire est de vous recommandons d'utiliser un ORM comme Linq-To-Sql ou NHibernate qui vous donnera opposez représentations de votre modèle de données qui font beaucoup plus simple pour gérer des choses complexes comme les opérations CRUD de type many-to-many.

Si un ORM ne fait pas partie de votre jeu d'outils, voici à quoi cela ressemblerait dans SOL.

 
Users  UserAddresses  Addresses 
=======  =============  ========= 
Id   Id    Id 
FirstName UserId   City 
LastName AddressId   State 
           Zip 

Nos tables sont jointes comme ceci:

 
    Users.Id -> UserAddresses.UserId 
    Addresses.Id -> UserAddresses.AddressId 
  • Tous les enregistrements des utilisateurs basés sur Addresses.Id
 
SELECT  Users.* 
FROM   Addresses INNER JOIN 
         UserAddresses ON Addresses.Id = UserAddresses.AddressId INNER JOIN 
         Users ON UserAddresses.UserId = Users.Id 
WHERE  (Addresses.Id = @AddressId) 
  • Tous les enregistrements d'adresses en fonction des utilisateurs .Id
 
SELECT  Addresses.* 
FROM   Addresses INNER JOIN 
         UserAddresses ON Addresses.Id = UserAddresses.AddressId INNER JOIN 
         Users ON UserAddresses.UserId = Users.Id 
WHERE  (Users.Id = @UserId) 
+0

Cela a résolu mon problème avec la sélection, mais je me bats un peu avec la mise à jour de la table de jonction. Quelle est la manière la plus intelligente de faire ceci? Je devrais mettre la clause WHERE à la fois le Userid et Addressid existants, non? J'ai essayé avec des tables temporaires, mais je n'arrive pas à avoir la syntaxe correcte. – Soeren

+0

Oui. Vous devez définir la clause de wehere à la fois l'UserId existant et AddressID – Micah

+0

@Micah si j'écris la première requête comme ceci:. 'SELECT * Les utilisateurs des utilisateurs INNER JOIN UserAddresses SUR Users.Id = UserAddresses.UsersID INNER JOIN Adresses ON UserAddresses.AddressId = Addresses.Id WHERE (Addresses.Id = @AddressId) ' Cela va-t-il et ce qui sera renvoyé? – Nuke

1
SELECT * 
FROM a 
WHERE id IN (SELECT aid FROM ab WHERE bid = 1234) 

ou

SELECT a.* 
FROM a 
JOIN ab ON a.id = ab.aid 
WHERE ab.aid = 12345 

Pour insérer, cela dépend de la base de données (par exemple, si les clés primaires sont des séquences, ou généré automatiquement générée à un autre mode ou simplement des clés composites). Mais vous avez juste besoin:

Pour que les données:

INSERT INTO a VALUES (...) 

Pour la relation.

INSERT INTO ab VALUES (...) 
+0

Ok, il est donc possible de le faire avec ou sans jointures? Dans le second exemple (avec la jointure), est-il nécessaire d'écrire "SELECT a. *" – Soeren

+0

select où() est généralement plus lent que select où existe() select * from a where exists (select * from b où a.Id = b.aId et b.Id = 1234) –

0

1) select tableA * de tableA rejoindre tableA_B sur tableA.id = tableA_B.idA où tableA_B.idB = une certaine valeur

2) 2 Sélectionnez 0 tableB. * À partir de la tableB .idB où tableA_B.idA = certaine valeur

3) insert dépend de votre base de données, mais insérer dans un, insérer dans b, puis insérer dans a_b; même avec des contraintes sur les tables, cela devrait fonctionner de cette façon.

indice: ne pas utiliser dans l'opérateur pour 1/2

1

Pour obtenir tous les enregistrements dans le tableau A en fonction de clé B, en anglais, vous voulez que les enregistrements dans le tableau A, qui ont une jointure record avec cette TableB clé (Supposons tableA_B deux Col. clés étrangères, (TabAFK et TabBFK)

Select * from TableA A 
    Where pK In (Select Distinct TabAFK From tableA_B 
       Where TabBFK = @TableBKeyValue) 

même chose pour l'autre direction

Select * from TableB B 
    Where pK In (Select Distinct TabBFK From tableA_B 
       Where TabAFK = @TableAKeyValue) 

pour insérer un nouvel enregistrement, faire un insert normale dans TableA et TableB au besoin ... les insertions dans le j table OIN (tableA_B) ne sont que les deux PKS des deux tables principales

Insert TableA (pk, [other columns]) Values(@pkValue, [other data) 
    Insert TableB (pk, [other columns]) Values(@pkValue, [other data) 

- Puis insérer dans une table de jointure pour chaque association qui existe ...

Insert tableA_B (TabAFK, TabBFK) Values(@PkFromA, @PkFromB)