Синтаксис UNION в Cakephp - PullRequest
       13

Синтаксис UNION в Cakephp

11 голосов
/ 21 августа 2010

Кто-нибудь знает хороший способ сделать запрос 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

Ответы [ 4 ]

13 голосов
/ 21 августа 2010

Слишком много кодеров пытаются ограничить себя функциональностью фреймворка.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);
5 голосов
/ 05 декабря 2013

Простой способ сделать это, который мы в настоящее время используем, - создать представление в MySQL или любой другой базе данных, которую вы используете.Затем вместо таблицы в вашей модели вы используете свое представление.Вы можете прочитать о синтаксисе создания представлений здесь: http://dev.mysql.com/doc/refman/5.6/en/create-view.html. Вы также можете использовать программное обеспечение, такое как HeidiSQL, чтобы помочь вам в создании представлений.

В таком случае в вашей модели будет что-то похожее:1006 *

Это позволяет вам по-прежнему использовать метод find() в CakePHP, который действительно приятно иметь.

Чтобы добиться максимальной производительности при просмотрах, вы должны обновить MySQL как минимум до версии 5.6.

3 голосов
/ 21 августа 2010

Используйте вид, затем выберите из этого:

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
1 голос
/ 13 февраля 2018

используйте такой код:

$friendsPosts= $this->Posts->find('all')
                ->contain(['Users', 'Languages', 'PostStates'])
                ->innerJoinWith('Users.Dusers', function ($q) {
                    return $q->where(['Dusers.id' => $this->Auth->user('id')]);
                });

        $posts= $this->Posts->find('all')
                ->where(['Posts.post_state_id' => 3])
                ->contain(['Users', 'Languages', 'PostStates']);

    $posts->union($friendsPosts);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...