首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CakePHP 3-无法生成带有WHERE...OR条件的查询

CakePHP 3-无法生成带有WHERE...OR条件的查询
EN

Stack Overflow用户
提问于 2019-07-29 15:15:43
回答 3查看 1.3K关注 0票数 2

CakePHP 3.7

我正在尝试生成一个使用WHERE...OR模式的查询。在MySQL中,执行并给出我想要的结果的等价结果是:

代码语言:javascript
复制
SELECT * FROM groups Groups WHERE (regulation_id = 1 AND label like '%labelling%') OR (id IN(89,1,8,232,228,276,268,294));

我已经阅读了文档的高级条件(https://book.cakephp.org/3.0/en/orm/query-builder.html#advanced-conditions)部分,但无法生成该查询。

假设表类是Groups,我有以下内容:

代码语言:javascript
复制
$Groups = TableRegistry::getTableLocator()->get('Groups');

$groups_data = $Groups->find('all')->where(['regulation_id' => 1);

$groups_data = $groups_data->where(['label LIKE' => '%labelling%']);

这将产生WHERE语句的第一个片段,即

代码语言:javascript
复制
SELECT * FROM groups Groups WHERE (regulation_id = 1 AND label like '%labelling%')

但是,我看不出如何附加OR条件,特别是因为不推荐orWhere()

因此,我已经尝试过了--甚至在docs中也给出了一个例子:

代码语言:javascript
复制
$in_array = [89,1,8,232,228,276,268,294]; // ID's for IN condition

$groups_data = $groups_data->where(['OR' => ['id IN' => $in_array]]);

但这只是将一个AND附加到我现有的SQL的内部:

代码语言:javascript
复制
SELECT * FROM groups Groups WHERE (regulation_id = 1 AND label like '%labelling%' AND id IN(89,1,8,232,228,276,268,294);

这不会产生正确的结果,因为语法不是运行此查询所需的。

如何“移出”WHERE,并附加类似于普通查询中的OR条件?

我根据文档多次使用QueryExpression,但所有这些都产生了PHP致命错误,这与Table类有关--我怀疑这是在正确的路线上。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-07-29 15:43:30

“移出”有点棘手,您必须明白,在内部,条件被推入\Cake\Database\Expression\QueryExpression对象,默认情况下使用AND连接语句,因此不管您推到哪个对象,都将使用AND添加。

当您创建OR语句时,它是使用所示的嵌套数组语法隐式创建的,或者使用表达式生成器显式地创建一个单独的、自包含的表达式,在该表达式中,它的各个部分将使用OR连接起来,它将编译自己(因为只有一个条件,您看不到任何OR),结果将在父表达式中使用,在您的情况下,父表达式是查询where子句的主/基表达式对象。

一次传递整个事件(通过数组语法或表达式),例如:

代码语言:javascript
复制
$groups_data->where([
    'OR' => [
        'AND' => [
            'regulation_id' => 1,
            'label LIKE' => '%labelling%'
        ],
        'id IN' => $in_array
    ]
]);

当然,如果需要,您可以动态地构建该数组,或者,如果出于某种原因需要使用对where()的单独调用,您可以重写条件(where()的第三个参数),并包含需要它们的当前条件:

代码语言:javascript
复制
$groups_data->where(
    [
        'OR' => [
            $groups_data->clause('where'),
            'id IN' => $in_array
        ]
    ],
    [], 
    true
);
票数 3
EN

Stack Overflow用户

发布于 2021-08-21 09:46:54

我知道这个问题很久了,但也许有人在找。这是我的解决方案:

代码语言:javascript
复制
protected $_hardValues= array(
    'company_id' => $company_from_session;
);
function beforeFind($event=null, $query = null, $options = null, $primary = true){
    $conds = [];
    $columns = $this->getSchema()->columns();
    foreach( $this->_hardValues as $field => $value){
        if( !is_null($value) && in_array($field, $columns) ){
            $conds[$this->_alias . '.' . $field] = $value;
        }
    }
    if( empty( $conds)) return true;
    $where = $query->clause('where'); //QueryExpression object;
    if( empty( $where)){
        $query->where($conds);
    }else{
        $where->add($conds);
    }
}
票数 0
EN

Stack Overflow用户

发布于 2022-01-26 16:44:43

在CakePHP 4.x中,记录在案的方法是:

代码语言:javascript
复制
$query = $articles->find()
->where([
    'author_id' => 3,
    'OR' => [['view_count' => 2], ['view_count' => 3]],
]);

请参阅文档

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57256735

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档