Php sql многие ко многим

Как вытащить данные, используя отношение многие ко многим, используя php и mysql

Я знаю, что этот вопрос можно задать несколько раз, но в какой-то момент я не могу понять по этой причине, я спрашиваю об этом. Вот вопрос У меня есть три таблицы, которые имеют отношение друг к другу, как отношение многих к многим Таблица

 Teacher Student Subject +-----------+ +-------------+ +---------------+ | id| name | | id| name | | id| name | +-----------+ +-------------+ +---------------+ | 1 | Ram | | 1 | Vikram | | 1 | Math | | 2 | Ajay | | 2 | Sunil | | 2 | English | | 3 | John | | 3 | Mohan | | 3 | Physics | | 4 | Eric | | 4 | Pawan | | 4 | Chemistry | | 5 | Manoj | | 5 | Deepak | | 5 | Biology | | 6 | Shiv | | 6 | Alex | | 6 | Social Sci| | | | | 7 | Shawn | | 7 | Hindi | | | | | 8 | Mark | | 8 | History | | | | | 9 | Joe | | | | +-----------+ +-------------+ +---------------+ 

Мне нужно вытащить данные, используя эти три таблицы с соединительной таблицей Таблица подключения (таблица соединений)

 Teacher_Subject Student_Subject +-----------------------+ +---------------------------+ |teacher_id |subject_id | | student_id | subject_id | +-----------------------+ +---------------------------+ | 1 | 7 | | 1 | 1 | | 1 | 8 | | 1 | 3 | | 2 | 1 | | 1 | 4 | | 2 | 3 | | 1 | 5 | | 3 | 2 | | 2 | 4 | | 4 | 6 | | 2 | 7 | | 5 | 4 | | 3 | 1 | | 6 | 5 | | 3 | 4 | | | | | 3 | 5 | | | | | 4 | 2 | | | | | 4 | 6 | +-----------------------+ +---------------------------+ 

с mysql и php есть ли способ вытащить эти данные с помощью одного запроса например Мне нужно извлекать данные, где

$result = [ 'name' => 'Vikram', 'subjects_teacher' => [ [ 'subject' => 'Math', 'teacher' => 'Ajay' ], [ 'subject' => 'Physics', 'teacher' => 'Ajay' ], [ 'subject' => 'Chemistry', 'teacher' => 'Manoj' ], [ 'subject' => 'Biology', 'teacher' => 'Shiv' ] ] ]; 

Изображение 80973

Связь Поэтому, пожалуйста, помогите мне в этом случае, потому что я видел много учебников и искал его, но не понял.

Читайте также:  Html display inline width

Где связь между таблицами? Мол, в приведенной выше структуре таблиц нет ничего, что позволило бы мне связать учителя «Аджай» с предметом «математика».

вам «просто» нужно соединить все 6 таблиц с некоторым «где x.id = y.id», а затем просмотреть результаты для построения массива. Вы что-нибудь пробовали?

@Jeff Джефф: да, я попробовал сначала, я вытащил всех учеников из таблицы учеников, затем, взяв идентификатор этого студента, я извлек данные из обеих таблиц с помощью соединения

Источник

mysql Связь «Многие ко Многим» — пример SQL кода таблиц с пояснениями. Таблица связи (ON DELETE CASCADE). Получение данных

vedro-compota's picture

Участники подают заявки на участие в номинациях в каком-то онлайн конкурсе — один участник может участвовать в любом числе номинаций (их много) и самих участников тоже может быть сколько угодно (тоже много) — а значит, здесь надо реализовать связь многие-ко-многим.

Далее будет использоваться синтаксис mysql.

Проектируем базу для связи Многие-ко-Многим — sql для создания таблиц

Нам потребуется создать три таблицы:

CREATE TABLE `Tickets` ( `ticketID` INT(11) NOT NULL AUTO_INCREMENT, `name` VARCHAR(255) NOT NULL DEFAULT '' COMMENT 'Имя участника/название организации', `info` VARCHAR(255) NULL DEFAULT '' COMMENT 'Информация о номинанте', PRIMARY KEY (`ticketID`) ) COMMENT='Заявки учасников конкурса' ENGINE=InnoDB ; CREATE TABLE `Nominations` ( `nominationID` INT(11) NOT NULL AUTO_INCREMENT, `title` VARCHAR(255) NULL DEFAULT NULL COMMENT 'Название номинации', PRIMARY KEY (`nominationID`) ) COMMENT='Номинации конкурса' ENGINE=InnoDB ; CREATE TABLE `Tickets_Nominations` ( `ticket_id` INT(11) NOT NULL, `nomination_id` INT(11) NOT NULL, PRIMARY KEY (`ticket_id`, `nomination_id`), INDEX `ticket_id` (`ticket_id`), INDEX `nomination_id` (`nomination_id`), CONSTRAINT `FK_Nominations` FOREIGN KEY (`nomination_id`) REFERENCES `Nominations` (`nominationID`) ON DELETE CASCADE, CONSTRAINT `FK_Ticket` FOREIGN KEY (`ticket_id`) REFERENCES `Tickets` (`ticketID`) ON DELETE CASCADE ) COMMENT='Таблица связи заявок участников и номинаций конкурса' ENGINE=InnoDB ;
  1. Свойство «ON DELETE CASCADE» —
    это значит, что если будет удалена запись в другой таблице, на которую ссылается данный кортеж (из таблицы связи), то и этот кортеж будет удалён целиком. В данном случае связь удаляется из таблицы если удалено хотя быть что-то одно из двух:
    • или заявка, на которую он ссылается
    • или номинация, на которую он ссылается

— таким образом мы переносим задачу удаления неактуальный связей с приложения на СУБД.

PRIMARY KEY (`ticket_id`, `nomination_id`),

— это автоматически делает (накладывает ограничение) данную комбинацию двух внешний ключей уникальной в рамках таблицы связи (т.е. уже не получится в данную таблицу два раза написать что «Вася подал заявку в номинацию «Лучший повар»»), на самом деле, в ряде случаев (например, для оперирования удобным численным ключом) можно было бы просто добавить обычный численные первичный ключ, а на пару внешних ключей каждого кортежа таблицы связи наложить требование уникальности (т.н. «уникальный составной индекс») — т.е. сделать нашу таблицу связи немного другой:, итак — таблица связи (другой вариант):

CREATE TABLE `Tickets_Nominations` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `ticket_id` INT(11) NOT NULL, `nomination_id` INT(11) NOT NULL, INDEX `ticket_id` (`ticket_id`), INDEX `nomination_id` (`nomination_id`), CONSTRAINT `FK_Nominations` FOREIGN KEY (`nomination_id`) REFERENCES `Nominations` (`nominationID`) ON DELETE CASCADE, CONSTRAINT `FK_Ticket` FOREIGN KEY (`ticket_id`) REFERENCES `Tickets` (`ticketID`) ON DELETE CASCADE, PRIMARY KEY (`id`), UNIQUE KEY `relation_row_unique` (`ticket_id`,`nomination_id`) ) COMMENT='Таблица связи заявок участников и номинаций конкурса' ENGINE=InnoDB ;

Извлечение данных для связи «многие ко многим» (SELECT)

Возникает логичный вопрос — как же получать данные из базы, используя таблицу связи?
Есть разные варианты для разных ситуаций, которые мы сейчас рассмотрим, но прежде чем проиллюстрировать их, заполните созданные выше таблицы данными с помощью такого sql (чтобы вы тоже могли поэкспериментировать с запросами)

Рассмотрим задачу извлечения участников, связанных с данной номинацией — или короче «номинации, и всех, кто подал в неё заявки» (алгоритм извлечения данных в обратную сторону — т.е. «участик и все его номинации» абсолютно аналогичен).
На практике приходится сталкиваться с двумя базовыми ситуациями:

  1. Извлечение одной сущности номинации и связанных с ней участников
  2. Извлечение списка сущностей номинаций и связанных с каждой из номинаций участников (т.е. фактически список участников для каждого элемента из списка номинаций).

Извлечение связанных (многие-ко-многим) данных для одной сущности

Пусть у нас известен id () номинации и мы хотим получить сведения об этой номинации и всех участниках в ней.
Во-первых, сделать это можно двумя sql запросами:

    Сначала просто получим кортеж этой номинации:

mysql> SELECT * FROM Nominations WHERE nominationID=4; +--------------+-----------------------------+ | nominationID | title | +--------------+-----------------------------+ | 4 | Лучшее пособие | +--------------+-----------------------------+
SELECT * FROM Tickets_Nominations LEFT JOIN Tickets ON ticket_id = ticketID WHERE Tickets_Nominations.nomination_id = 4;
+-----------+---------------+----------+-------------------------- +----------------------------------------------+ | ticket_id | nomination_id | ticketID | name | info | +-----------+---------------+----------+---------------------------+----------------------------------------------+ | 3 | 4 | 3 | Программирование для всех | Некоммерческая образовательная организация | 4 | 4 | 4 | Юный программист | Кружок для детей в д. Простоквашино | 5 | 4 | 5 | IT FOR FREE | Русскоязычное IT-сообщество с уклоном в web | 6 | 4 | 6 | Саша Петров | Студент 2 курса, автор пособия по SQL

Если вам требуется от массива связанных сущностей только одно поле (напр. имена участников), то решить задачу можно вообще одним sql запросом, используя группировку (GROUP BY) и применимую к группируемым значения колонки функцию конкатенации GROUP_CONCAT():

SELECT Nominations.*, GROUP_CONCAT(Tickets.name SEPARATOR ', ') as participants_names FROM Nominations LEFT JOIN Tickets_Nominations ON Nominations.nominationID = Tickets_Nominations.nomination_id LEFT JOIN Tickets ON Tickets.ticketID = Tickets_Nominations.ticket_id WHERE Tickets_Nominations.nomination_id = 4 GROUP BY Nominations.nominationID;

Получим единственный кортеж:

+--------------+-----------------------------+-----------------------------------------------------------------------------------------------------------------------+ | nominationID | title | participants_names | +--------------+-----------------------------+-----------------------------------------------------------------------------------------------------------------------+ | 4 | Лучшее пособие | Программирование для всех, Юный программист, IT FOR FREE, Саша Петров | +--------------+-----------------------------+-----------------------------------------------------------------------------------------------------------------------+
  • провели сразу тройной JOIN, как бы поставив таблицу связи между таблицами номинаций и заявок.
  • нас интересовали имена участников для 4 номинации — поэтому использовали WHERE Tickets_Nominations.nomination_id = 4
  • Группировка (чтобы в итоге получить только одну строку-кортеж) проходила по id номинации (Nominations.nominationID)
  • Сконкатенированному полю мы назначили псевдоним (participants_names)

Плюсом такого подхода является то, что в приложении можно использовать готовую строку participants_names, а минусом то, что с этим значением уже нельзя работать как с массивом, явно не преобразовав.

Извлечение списка сущностей со связанными данными

  1. Cначала извлечь (SELECT) необходимые номинации (или вообще все),
  2. а потом уровне приложения в цикле извлечь связанные данные для каждой номинации отдельно (как это показано выше) — это не оптимальный способ так как он порождает много запросов к БД (так что если список номинаций — — или иных сущностей велик, то и запросы сильно скажутся на суммарном времени выполнении скрипта и нагрузке на процессор)

Key Words for FKN + antitotal forum (CS VSU):

  • ON DELETE CASCADE
  • многие ко многим
  • составной уникальный индекс
  • пример
  • каскадное удаление
  • таблица связи
  • mySQL
  • mysql многие ко многим пример
  • связь многие ко многим sql пример
  • многие ко многим пример
  • связь многие ко многим подробное объяснение
  • как извлекать данные
  • select многие ко многим

Источник

Оцените статью