任何人都知道在CakePHP中进行UNION查询的好方法吗?我想避免使用$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
答案 0 :(得分:13)
太多的程序员试图将自己局限于框架的功能。别。使用框架提供的内容。如果它没有您寻求的功能,那么:
或
通常情况下,开发人员会尝试将方形钉子敲入一个圆孔中,然后做太多额外的工作,这实际上只会使代码变得复杂。退后一步,问一下为什么要开始使用框架。它为非结构化语言带来了结构。它为构建应用程序提供了坚实的可重用基础。它并不是一个让自己陷入困境的盒子。
更新:我花了一分钟时间阅读Complex Find Conditions并找到了答案:
$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);
答案 1 :(得分:5)
我们目前使用的一种简单方法是在MySQL或您使用的任何数据库中创建视图。然后,您可以使用视图,而不是在模型中使用表格。您可以在此处阅读有关视图创建语法的信息:http://dev.mysql.com/doc/refman/5.6/en/create-view.html。您还可以使用HeidiSQL等软件来帮助您创建视图。
您的模型中会有这样的内容:
class Contenu extends AppModel {
public $useTable = 'v_contenu';
这允许你仍然使用CakePHP中的find()
方法,这非常好。
要获得视图的最佳性能,您应该将MySQL更新到至少5.6版本。
答案 2 :(得分:3)
使用视图,然后从中选择:
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
答案 3 :(得分:1)
使用这样的代码:
$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);