Примеры запросов в отношениях «многие ко многим» - PullRequest
10 голосов
/ 06 января 2009

Ух ты, трудно найти простое объяснение этой теме. Простое отношение «многие ко многим».

Три таблицы, таблица A, таблица B и соединительная таблица A_B.

Я знаю, как установить отношения с ключами и всем, но я немного запутался, когда пришло время выполнять запросы INSERT, UPDATE и DELETE ....

По сути, я ищу пример, показывающий:

  1. Как получить все записи в Таблице A на основе идентификатора в Таблице B

  2. Как получить все записи в таблице B на основе идентификатора в таблице A

3 Как ВСТАВИТЬ в TableA или TableB, а затем сделать соответствующую INSERT в соединительной таблице для установления соединения.

Я не ищу решения для конкретного проекта, просто несколько общих примеров, которые можно применить. Может быть, у вас что-то валяется?

Ответы [ 4 ]

6 голосов
/ 06 января 2009

Первое, что я хотел бы сделать, это порекомендовать использовать ORM, например Linq-To-Sql или NHibernate , который даст вам объектные представления вашей модели данных, которые значительно упростят ее. для обработки сложных вещей, таких как операции CRUD «многие ко многим».

Если ORM не является частью вашего набора инструментов, то вот как это будет выглядеть в SOL.

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

Наши таблицы объединяются так:

   Users.Id -> UserAddresses.UserId
   Addresses.Id -> UserAddresses.AddressId
  • Все записи пользователей на основе адресов. Ид.
SELECT        Users.*
FROM            Addresses INNER JOIN
                         UserAddresses ON Addresses.Id = UserAddresses.AddressId INNER JOIN
                         Users ON UserAddresses.UserId = Users.Id
WHERE        (Addresses.Id = @AddressId)
  • Все записи в адресах основаны на Users.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)
1 голос
/ 06 января 2009

Чтобы получить все записи в таблице A на основе ключа B, на английском языке, вам нужны записи в таблице A, которые имеют запись Join с этим ключом TableB (Предположим, что таблица A_B имеет два столбца внешнего ключа (TabAFK и TabBFK)

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

То же самое для другого направления

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

Чтобы вставить новую запись, выполните обычную вставку в TableA и TableB, если необходимо ... Вставки в таблицу соединений (tableA_B) - это всего лишь два пакета из двух основных таблиц

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

- Затем вставьте в таблицу соединений для каждой существующей ассоциации ...

  Insert tableA_B (TabAFK, TabBFK)  Values(@PkFromA,  @PkFromB)  
1 голос
/ 06 января 2009
SELECT *
FROM a
WHERE id IN (SELECT aid FROM ab WHERE bid = 1234)

или

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

Чтобы вставить, это зависит от вашей базы данных (например, являются ли первичные ключи последовательностями, автоматически сгенерированными или сгенерированными каким-либо другим способом или просто составными ключами). Но вам просто нужно:

Для этих данных:

INSERT INTO a VALUES (...)

Для отношений:

INSERT INTO ab VALUES (...)
0 голосов
/ 06 января 2009

1) выберите таблицу A. * из таблицы A, присоединитесь к таблице A_B на tableA.id = tableA_B.idA где tableA_B.idB = somevalue

2) выберите tableB. * из таблицыB слева присоединить tableA_B к tableB.id = tableA_B.idB где tableA_B.idA = somevalue

3) вставка зависит от вашей базы данных, но вставьте в a, вставьте в b, а затем вставьте в a_b; даже с ограничениями на таблицы это должно работать таким образом.

подсказка: не используйте оператор IN для 1/2

...