Сегодня мы поговорим о том, как программно объединять таблицы в 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