Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/266.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Cakephp中的联合语法_Php_Sql_Mysql_Cakephp_Union - Fatal编程技术网

Cakephp中的联合语法

Cakephp中的联合语法,php,sql,mysql,cakephp,union,Php,Sql,Mysql,Cakephp,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

有人知道用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

使用视图,然后从中选择:

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

太多的程序员试图将自己局限于框架的功能。不要。使用框架提供的内容。如果它没有您寻求的功能,则:

  • 将所需的功能编码到类扩展中

  • 在框架内自定义旋转代码以满足您的需要
通常,开发人员试图将一个方形的钉子敲入一个圆孔,结果做了太多额外的工作,这只会使代码变得复杂。退一步,问一下为什么要从这个框架开始。它将结构化引入非结构化语言。它为构建应用程序提供了坚实的可重用基础。它不是一个用来限制自己的盒子

更新:我花了一分钟阅读并找到了您的答案:

$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);

我们目前使用的一种简单方法是在MySQL或任何您使用的数据库中创建一个视图。然后,不用模型中的表,而是使用视图。您可以在此处阅读有关视图创建语法的内容:。您还可以使用HeidiSQL之类的软件来帮助您创建视图

然后,您的模型中会有类似的内容:

class Contenu extends AppModel {
    public $useTable = 'v_contenu';
这允许您仍然使用CakePHP中的
find()
方法,这非常好

为了获得视图的最佳性能,您应该将MySQL更新到至少5.6版。

使用如下代码:

$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);

有没有任何理由希望避免$this->query?首先,如果您不打算尝试以框架的本机样式编写应用程序,那么它就无法实现使用框架的目的。大多数
SELECT
查询实际上可以使用1.3中的
find()
执行。另外,
find()
还受益于数据源驱动程序针对SQL注入的内置保护,而
query()
是一种您必须逃避的直接查询。也就是说,
UNION
可能是使用
find()
无法执行的少数几类查询之一。您运行的MySQL UNION示例有效吗?列出的一个不起作用。我认为对于框架的目的存在一些混淆。框架的设计不一定要使代码跨数据库兼容。此外,您不应将站点的功能限制为框架内的限制。设计了一个框架来将UI与域逻辑分离。它还通过引入结构和组织来增强开发,并提供可重用的代码。如果你只做框架允许的那些事情,你的能力就会受到限制。@cdburges:我还没有工作示例。事实上,我需要做
完全连接
,但MySQL不支持。因此,我认为我不是第一个遇到这个问题的人,可能已经找到了解决方案,因此我发布了这个问题。这是一个很好的可能的解决方案,但请参阅关于在Cake中使用视图的免责声明:恐怕这在其他数据库(如SQLlite)中不起作用。@bancer:你确定吗?SQLite的文档表明它支持视图并使用相同的
createview
语法。也许我的查询不适合独立于数据库?首先要做的是检查是否有可能解决框架功能的问题。当然,框架不能限制一个程序员。更新时使用+1。这是正确的方向。稍后,我将更仔细地看一下代码。感谢您推荐开发人员不要将自己局限于框架提供的功能。我经常看到人们因为“这不是蛋糕式的方式”而否定一个完全有效的解决方案。这是一个非常好的解决方案