Сегодня мы поговорим о том, как программно объединять таблицы в Magento 2. Иногда вам нужно получить коллекцию соединений с данными коллекции продуктов или данными коллекции категорий, или коллекцией заказов, или пользовательской коллекцией таблиц. Чтобы вам было проще это сделать, команда разработчиков из Magenest рекомендует тему объединения таблиц в Magento2. Вот так.

Как объединить таблицы в SQL?

Оператор SQL Join используется для объединения данных или строк из двух или более таблиц на основе общего поля между ними. Различные типы соединений:

  • INNER JOIN: возвращает записи, имеющие совпадающие значения в обеих таблицах.
  • LEFT JOIN: возвращает все записи из левой таблицы и соответствующие записи из правой таблицы.
  • RIGHT JOIN: возвращает все записи из правой таблицы и соответствующие записи из левой таблицы.
  • FULL JOIN: возвращает все записи из обеих таблиц. (мы столько не используем)

Для этого примера у нас есть следующие таблицы:

Director_idName1Magenest Director2Magenest3Son Tung4Cris5Magento2Magenest_director

movie_idnamedescriptionratingdirector_id1Гарри ПоттерФэнтези112ПассажирДействие223КоварныйУжас434ПокемонАниме44Magenest_movie

actor_idname1Rowan2Tung3Satoshi4MagenestMagenest_actor

movie_idactor_id112223334441Magenest_movie_actor

И их отношения:

Мы хотим получить все записи с совпадающими значениями из Magenest_movie, Magenest_director и Magenest_actor. Запрос будет следующим:

SELECT `main_table`.name AS `movie`, `main_table`.description ,`main_table`.rating , `magenest_director`.`name` AS `director`, `magenest_actor`.name AS `actor` 
FROM `magenest_movie` AS `main_table` 
INNER JOIN `magenest_director` ON main_table.director_id=magenest_director.director_id 
INNER JOIN `magenest_movie_actor` ON main_table.movie_id=magenest_movie_actor.movie_id 
INNER JOIN `magenest_actor` ON magenest_actor.actor_id=magenest_movie_actor.actor_id;

Результат:

фильмописаниерейтингрежиссерАктерГарри ПоттерФэнтези1Magenest режиссерРоуэнПассажирAction2MagenestTungPassengerAction2MagenestSatoshiКоварныйУжас4Son TungSatoshiPokemonАниме4CrisMagenestPokemonАниме4CrisRowan

Затем получите имена всех режиссеров и названия соответствующих фильмов:

SELECT `main_table`.name as `movie`,`magenest_director`.name AS `director` 
FROM `magenest_movie` AS `main_table` 
RIGHT  JOIN `magenest_director` ON main_table.director_id=magenest_director.director_id

кинорежиссерГарри ПоттерМагенест режиссерПассажирМагенестКоварныйСын ТунгПокемонКрисНуллМагенто2

При использовании LEFT JOIN в этом случае результат будет таким:

кинорежиссерГарри ПоттерMagenest режиссерПассажирMagenestInsidiousSon TungPokemonCris

Преобразование запросов таблицы соединения SQL в коды Magento 2

Мы предполагаем, что упомянутые таблицы уже существуют в Magento со своими классами Model, Resource Model и Collection:

Начнем с класса коллекции таблицы фильмов:

<?php
namespace Vendor\Namespace\Model\ResourceModel\Movie;
class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection
{
 
   protected function _construct()
   {
       $this->_init('Vendor\Namespace\Model\Movie', 'Vendor\Namespace\Model\ResourceModel\Movie');
   }
 
}

Запрос ниже:

SELECT `main_table`.name AS `movie`, `main_table`.description ,`main_table`.rating , `magenest_director`.`name` AS `director`, `magenest_actor`.name AS `actor` 
FROM `magenest_movie` AS `main_table` 
INNER JOIN `magenest_director` ON main_table.director_id=magenest_director.director_id
INNER JOIN `magenest_movie_actor` ON 
main_table.movie_id=magenest_movie_actor.movie_id 
INNER JOIN `magenest_actor` ON magenest_actor.actor_id=magenest_movie_actor.actor_id;

Может быть выполнен в пользовательской функции в классе Collection как:

public function joinTable(){
       $actorTable = $this->getTable('magenest_actor');
       $actormovieTable = $this->getTable('magenest_movie_actor');
       $directorTable = $this->getTable('magenest_director');
       $result = $this
       ->addFieldToSelect('name','movie')
       ->addFieldToSelect('description')
       ->addFieldToSelect('rating')
       ->join($directorTable, 'main_table.director_id='.$directorTable.'.director_id',['director' => 'name'])
       ->join($actormovieTable,'main_table.movie_id='.$actormovieTable.'.movie_id',null)
       ->join($actorTable,$actorTable.'.actor_id='.$actormovieTable.'.actor_id',['actor' => 'name']);
       return $result->getSelect();
   }

Примечание. В коллекции Magenest_movie функция Magenest_movie автоматически возвращает main_table.

Поэтому вот запрос и результаты:

LEFT JOIN и RIGHT JOIN могут быть выполнены аналогичным образом. Вот пример использования RIGHT JOIN.

ВЫБЕРИТЕ `main_table`.name как `movie`,`magenest_director`.name КАК `director`

ОТ `magenest_movie` КАК `main_table`

ПРАВОЕ СОЕДИНЕНИЕ `magenest_director` ONmain_table.director_id=magenest_director.director_id

ublic function testJoinRight(){
       $directorTable = $this->getTable('magenest_director');
       $join = $this->addFieldToSelect('name','movie')
       ->getSelect()
       ->joinRight($directorTable,
       'main_table.director_id='.$directorTable.'.director_id',
       ['director' => 'name']);
       return $join;
   }

Примечание. Другие директивы можно найти в разделе Magento\Framework\Db\Select.

Источник: https://magenest.com/en/how-to-join-tables-programmatically-in-magento2/

#join_tables_programmatically_in_magento2
#magenest
#onestopsolution