Кто-нибудь знает хороший способ сделать запрос UNION в CakePHP? Я бы хотел избежать использования $this->query();
,
С двумя таблицами t1, t2:
SELECT * FROM t1 LEFT JOIN t2 ON t1.id = t2.id UNION SELECT * FROM t1 RIGHT JOIN t2 ON t1.id = t2.id
С тремя таблицами t1, t2, t3:
SELECT * FROM t1 LEFT JOIN t2 ON t1.id = t2.id LEFT JOIN t3 ON t2.id = t3.id UNION SELECT * FROM t1 RIGHT JOIN t2 ON t1.id = t2.id LEFT JOIN t3 ON t2.id = t3.id UNION SELECT * FROM t1 RIGHT JOIN t2 ON t1.id = t2.id RIGHT JOIN t3 ON t2.id = t3.id
Слишком много кодеров пытаются ограничить функциональность фреймворка. DO NOT. Используйте то, что предоставляет инфраструктура. Если у вас нет функциональности, которую вы ищете, то либо:
или
Зачастую разработчики пытаются забить квадратную привязку в круглое отверстие и завершить слишком много лишней работы, которая действительно только делает код сложным. Сделайте шаг назад и спросите, почему вы используете фреймворк для начала. Он привносит структуру в неструктурированный язык. Он обеспечивает надежную основу многократного использования для создания вашего приложения. Он не предназначен для того, чтобы вставлять себя и быть ограниченным.
ОБНОВЛЕНИЕ: я потратил минуту, чтобы прочитать « Комплексные условия поиска» и нашел ответ:
$joins = array( array( 'table' => 'test_twos', 'alias' => 'TestTwo', 'type' => 'LEFT', 'conditions' => array( 'TestTwo.id = TestOne.id', ) ), array( 'table' => 'test_threes', 'alias' => 'TestThree', 'type' => 'LEFT', 'conditions' => array( 'TestThree.id = TestOne.id', ) ) ); $dbo = $this->getDataSource(); $subQuery = $dbo->buildStatement( array( 'fields' => array('*'), 'table' => $dbo->fullTableName($this), 'alias' => 'TestOne', 'limit' => null, 'offset' => null, 'joins' => $joins, 'conditions' => null, 'order' => null, 'group' => null ), $this->TestOne ); $query = $subQuery; $query .= ' UNION '; $joins = array( array( 'table' => 'test_twos', 'alias' => 'TestTwo', 'type' => 'LEFT', 'conditions' => array( 'TestTwo.id = TestOne.id', ) ), array( 'table' => 'test_threes', 'alias' => 'TestThree', 'type' => 'RIGHT', 'conditions' => array( 'TestThree.id = TestOne.id', ) ) ); $dbo = $this->getDataSource(); $subQuery = $dbo->buildStatement( array( 'fields' => array('*'), 'table' => $dbo->fullTableName($this), 'alias' => 'TestOne', 'limit' => null, 'offset' => null, 'joins' => $joins, 'conditions' => null, 'order' => null, 'group' => null ), $this->TestOne ); $query .= $subQuery; pr($query);
Используйте представление, затем выберите из него:
create view my_union as SELECT * FROM t1 LEFT JOIN t2 ON t1.id = t2.id LEFT JOIN t3 ON t2.id = t3.id UNION SELECT * FROM t1 RIGHT JOIN t2 ON t1.id = t2.id LEFT JOIN t3 ON t2.id = t3.id UNION SELECT * FROM t1 RIGHT JOIN t2 ON t1.id = t2.id RIGHT JOIN t3 ON t2.id = t3.id
В вашем коде:
select * from my_union
Простым способом сделать это, который мы в настоящее время используем, является создание представления в MySQL или любой другой базе данных, которую вы используете. Затем вместо использования таблицы в вашей модели вы используете свое представление. Вы можете прочитать о синтаксисе создания представлений здесь: http://dev.mysql.com/doc/refman/5.6/en/create-view.html . Вы также можете использовать программное обеспечение, такое как HeidiSQL, чтобы помочь вам создать представление.
Тогда у вас будет что-то подобное в вашей модели:
class Contenu extends AppModel { public $useTable = 'v_contenu';
Это позволяет использовать метод find()
в CakePHP, что очень приятно иметь.
Чтобы получить максимальную производительность при просмотре, вы должны обновить MySQL до версии 5.6.