2009-01-06 67 views
10

Rất tiếc, thật khó để tìm một lời giải thích đơn giản cho chủ đề này. Một mối quan hệ nhiều-nhiều.Ví dụ truy vấn trong mối quan hệ nhiều-nhiều-

Ba bảng, tableA, tableB và bảng giao diệnA_B.

Tôi biết làm thế nào để thiết lập mối quan hệ, với các phím và tất cả, nhưng tôi nhận được một chút nhầm lẫn khi thời gian đến để thực hiện câu lệnh INSERT, UPDATE và DELETE truy vấn ....

Về cơ bản, những gì tôi đang tìm kiếm là một ví dụ cho thấy:

  1. Làm thế nào để có được tất cả các bản ghi trong TableA, dựa trên một ID trong TableB

  2. Làm thế nào để có được tất cả các bản ghi trong TableB, dựa trên một ID trong TableA

3 Làm thế nào để chèn vào một trong hai TableA hoặc TableB, và sau đó làm cho INSERT thích hợp trong bảng đường giao nhau để tạo kết nối ..

Tôi không tìm kiếm một giải pháp cho một dự án cụ thể, chỉ là một vài ví dụ chung có thể được áp dụng. Có lẽ bạn có một cái gì đó nằm xung quanh?

Trả lời

6

Điều đầu tiên tôi sẽ làm là khuyên bạn sử dụng một ORM như Linq-To-Sql hoặc NHibernate mà sẽ cung cấp cho bạn phản đối cơ quan đại diện của mô hình dữ liệu của bạn mà làm cho nó nhiều đơn giản hơn để xử lý những thứ phức tạp như nhiều hoạt động CRUD.

Nếu một ORM không phải là một phần của bộ công cụ của bạn thì đây là cách nó sẽ trông như thế nào trong SOL.

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

bảng của chúng tôi được tham gia như thế này:

 
    Users.Id -> UserAddresses.UserId 
    Addresses.Id -> UserAddresses.AddressId 
  • Tất cả các bản ghi trong Người dùng dựa trên 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) 
  • Tất cả các bản ghi trong địa chỉ dựa trên người dùng .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

Điều này giải quyết được vấn đề của tôi khi lựa chọn, nhưng tôi đang phải vật lộn một chút với việc cập nhật bảng nối. Cách thông minh nhất để làm điều này là gì? Tôi phải đặt mệnh đề WHERE cho cả Userid và Addressid hiện tại, đúng không? Tôi đã thử với các bảng tạm thời, nhưng dường như tôi không thể có được cú pháp đúng. – Soeren

+0

Có. Bạn cần phải đặt mệnh đề wehere cho cả Userid hiện có và Addressid – Micah

+0

@Micah Nếu tôi viết truy vấn đầu tiên như thế này: 'SELECT Users. * FROM Users INNER JOIN UserAddresses ON Users.Id = UserAddresses.UsersID INNER JOIN Địa chỉ ON UserAddresses.AddressId = Addresses.Id WHERE (Addresses.Id = @AddressId) ' Nó có ổn không và những gì sẽ được trả lại? – Nuke

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

hoặc

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

Để chèn, mà phụ thuộc vào cơ sở dữ liệu của bạn (ví dụ như các phím chính là từ chuỗi, tạo tự động hoặc được tạo ra trong một số thời trang khác hoặc phím đơn giản composite). Nhưng bạn chỉ cần:

Đối với dữ liệu mà:

INSERT INTO a VALUES (...) 

Đối với các mối quan hệ:.

INSERT INTO ab VALUES (...) 
+0

Ok, do đó, nó có thể làm điều này có hoặc không có tham gia? Trong ví dụ thứ hai (có tham gia), cần phải viết "SELECT a. *" – Soeren

+0

chọn nơi in() thường chậm hơn chọn nơi tồn tại() chọn * từ nơi tồn tại (chọn * từ b trong đó a.Id = b.aId và b.Id = 1234) –

0

1) chọn tableA * từ tableA tham gia tableA_B trên tableA.id = tableA_B.idA trong đó tableA_B.idB = somevalue

2) chọn bảngB. * Từ tableB bảng kết nối tráiA_B trên bảngB.id = tableA_B .idB trong đó bảngA_B.idA = somevalue

3) chèn phụ thuộc vào cơ sở dữ liệu của bạn, nhưng chèn vào, chèn vào b và sau đó chèn vào a_b; thậm chí với những ràng buộc trên các bảng, nó sẽ hoạt động theo cách đó.

gợi ý: không sử dụng IN điều hành cho 1/2

1

Để có được tất cả các bản ghi trong bảng A dựa trên chủ chốt trong B, bằng tiếng Anh, bạn muốn ghi trong Bảng A trong đó có một kỷ lục gia với TableB chính (Giả tableA_B có hai cols chính nước ngoài, (TabAFK và TabBFK)

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

Cùng một điều cho một hướng khác

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

để chèn một kỷ lục mới, làm một chèn bình thường vào TableA và TableB khi cần thiết ... Miếng chèn vào j bảng oin (tableA_B) chỉ là hai PKS từ hai bảng chính

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

- Sau đó chèn vào Tham bảng cho mỗi hiệp hội tồn tại ...

Insert tableA_B (TabAFK, TabBFK) Values(@PkFromA, @PkFromB) 
Các vấn đề liên quan