2009-01-06 13 views
10

Wow, trudno jest znaleźć proste wyjaśnienie tego tematu. Prosta relacja wiele do wielu.Przykłady zapytań w relacjach wiele do wielu

Trzy tabele, tabela A, tabela B i tabela połączeń A_B.

wiem jak skonfigurować relacji, z klawiszy i wszystkich, ale ja się trochę zdezorientowany, kiedy nadejdzie czas, aby wykonać INSERT, UPDATE i DELETE zapytań ....

Zasadniczo co szukam jest to przykład, który pokazuje:

  1. Jak uzyskać wszystkie rekordy w TableA, w oparciu o ID w TableB

  2. Jak zdobyć wszystkie rekordy w TableB, na podstawie identyfikatora w TableA

3 Jak wstawić w dowolnym TableA lub TableB, a następnie dokonać odpowiedniego insertu w tabeli przyłączeniowej do nawiązania połączenia ..

Nie szukam rozwiązania do konkretnego projektu, po prostu kilka ogólnych przykładów, które można zastosować. Może masz coś w pobliżu?

Odpowiedz

6

Pierwszą rzeczą, którą chciałbym zrobić, to zalecamy korzystanie ORM jak Linq-To-Sql lub NHibernate który daje obiekt reprezentacje swojej modeli danych, które czynią ją znacznie prostsze w obsłudze skomplikowane operacje, takie jak wiele-do-wielu operacji CRUD.

Jeśli ORM nie jest częścią zestawu narzędzi, oto jak będzie wyglądał SOL.

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

naszych stołach są połączone tak:

 
    Users.Id -> UserAddresses.UserId 
    Addresses.Id -> UserAddresses.AddressId 
  • wszystkie rekordy użytkowników na podstawie 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) 
  • wszystkie rekordy w adresach oparte na użytkownikach .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

Rozwiązało to mój problem z wyborem, ale trochę się zmagam z aktualizacją tabeli skrzyżowań. Jaki jest najmądrzejszy sposób na zrobienie tego? Musiałbym ustawić klauzulę WHERE zarówno dla istniejącego Userid i Addressid, prawda? Próbowałem już z tabelami tymczasowymi, ale wydaje mi się, że nie można uzyskać prawidłowej składni. – Soeren

+0

Tak. Trzeba ustawić się na klauzulę wehere zarówno istniejącego identyfikatora użytkownika i Addressid – Micah

+0

@Micah Co jeśli piszę pierwsze zapytanie takiego. 'wybrać użytkowników * od użytkowników INNER JOIN UserAddresses NA Users.Id = UserAddresses.UsersID WEWNĘTRZNEJ DOŁĄCZ Adresy ON UserAddresses.AddressId = Adresy.Id WHERE (Adresy.Id = @AddressId) ' Czy wszystko będzie dobrze i co zostanie zwrócone? – Nuke

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

lub

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

Aby wstawić, to zależy od bazy danych (na przykład, czy klucze podstawowe są z sekwencji, generowane automatycznie wygenerowane lub w jakiś inny sposób lub po prostu kluczy kompozytowych). Ale wystarczy:

Dla tych danych:

INSERT INTO a VALUES (...) 

dla relacji.

INSERT INTO ab VALUES (...) 
+0

Ok, więc jest to można to zrobić z połączeniami lub bez? W drugim przykładzie (z łączeniem) konieczne jest wpisanie "WYBIERZ a. *" – Soeren

+0

wybierz gdzie w() jest zwykle wolniejsze niż wybierz gdzie istnieje() wybierz * z a gdzie istnieje (wybierz * z b gdzie a.Id = b.aId i b.Id = 1234) –

0

1) TABLEA select * from TableA dołączyć tableA_B na tableA.id = tableA_B.idA gdzie tableA_B.idB = somevalue

2) wybierz tableB. * Od tableB left join tableA_B on tableB.id = tableA_B .idB gdzie tableA_B.idA = somevalue

3) insert zależy od bazy danych, ale wstaw do a, wstaw do b, a następnie wstaw do a_b; nawet z ograniczeniami na tabelach powinien działać w ten sposób.

podpowiedź: Nie stosować u operatora 1/2

1

Aby uzyskać wszystkie rekordy w tabeli A w oparciu o klucz w B, w języku angielskim, chcesz rekordy w tabeli A, które mają zapis przyłączyć że TableB klucz (Załóżmy tableA_B ma dwa klucz obcy cols (TabAFK i TabBFK)

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

samo na innym kierunku

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

Aby wstawić nowy rekord, zrobić normalną wkładkę do TableA i TableB jako niezbędny ... Wstawki w j Stół OIN (tableA_B) są tylko dwa PKS z dwóch głównych tabel

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

- Następnie wstawić Dołącz tabelę dla każdego związku, który istnieje ...

Insert tableA_B (TabAFK, TabBFK) Values(@PkFromA, @PkFromB) 
Powiązane problemy