CakePHP 3 - 无法生成具有 WHERE...OR 条件的查询
CakePHP 3 - unable to generate a query with WHERE...OR conditions
蛋糕PHP3.7
我正在尝试生成一个使用 WHERE...OR
模式的查询。 MySQL 中的等效项 - 执行并给出我想要的结果是:
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) 部分,但无法生成该查询。
假设 Table class 是 Groups
我有这个:
$Groups = TableRegistry::getTableLocator()->get('Groups');
$groups_data = $Groups->find('all')->where(['regulation_id' => 1);
$groups_data = $groups_data->where(['label LIKE' => '%labelling%']);
这将生成 WHERE
语句的第一段,即
SELECT * FROM groups Groups WHERE (regulation_id = 1 AND label like '%labelling%')
但是我看不到如何附加 OR
条件,尤其是因为 orWhere()
已被弃用。
所以我试过了 - 这甚至在文档中作为示例给出:
$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:
的内部
SELECT * FROM groups Groups WHERE (regulation_id = 1 AND label like '%labelling%' AND id IN(89,1,8,232,228,276,268,294);
这不会产生正确的结果,因为语法不是 运行 此查询所需的语法。
如何 WHERE
的 "move out" 并附加一个 OR
条件,就像普通查询中那样?
我根据文档使用 QueryExpression
进行了多次尝试,但所有这些都产生了 PHP 致命错误,说明与 Table class 有关 - 我怀疑这是否正确。
"moving out" 有点棘手,你必须明白在内部条件被推入一个 \Cake\Database\Expression\QueryExpression
对象,默认情况下使用 AND
连接语句,所以无论你继续下去,将使用 AND
.
添加
当您创建 OR
语句时,无论是隐含地使用所示的嵌套数组语法,还是显式地使用表达式生成器,这都会创建一个单独的、自包含的表达式,其中其部分使用OR
,它将自行编译(因为只有一个条件,你看不到任何 OR
),结果将用于父表达式,在你的情况下是main/base 查询 where 子句的表达式对象。
一次传递整个东西(通过数组语法或表达式),例如:
$groups_data->where([
'OR' => [
'AND' => [
'regulation_id' => 1,
'label LIKE' => '%labelling%'
],
'id IN' => $in_array
]
]);
当然,如果需要,您可以动态构建该数组,或者,如果您出于某种原因需要单独调用 where()
,例如,您可以覆盖条件([=18 的第三个参数=]),并在您需要的地方包括当前的:
$groups_data->where(
[
'OR' => [
$groups_data->clause('where'),
'id IN' => $in_array
]
],
[],
true
);
我知道这个问题已经过时了,但也许有人正在寻找。这是我的解决方案:
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);
}
}
自 CakePHP 4.x 起,记录在案的执行此操作的方法是:
$query = $articles->find()
->where([
'author_id' => 3,
'OR' => [['view_count' => 2], ['view_count' => 3]],
]);
蛋糕PHP3.7
我正在尝试生成一个使用 WHERE...OR
模式的查询。 MySQL 中的等效项 - 执行并给出我想要的结果是:
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) 部分,但无法生成该查询。
假设 Table class 是 Groups
我有这个:
$Groups = TableRegistry::getTableLocator()->get('Groups');
$groups_data = $Groups->find('all')->where(['regulation_id' => 1);
$groups_data = $groups_data->where(['label LIKE' => '%labelling%']);
这将生成 WHERE
语句的第一段,即
SELECT * FROM groups Groups WHERE (regulation_id = 1 AND label like '%labelling%')
但是我看不到如何附加 OR
条件,尤其是因为 orWhere()
已被弃用。
所以我试过了 - 这甚至在文档中作为示例给出:
$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:
SELECT * FROM groups Groups WHERE (regulation_id = 1 AND label like '%labelling%' AND id IN(89,1,8,232,228,276,268,294);
这不会产生正确的结果,因为语法不是 运行 此查询所需的语法。
如何 WHERE
的 "move out" 并附加一个 OR
条件,就像普通查询中那样?
我根据文档使用 QueryExpression
进行了多次尝试,但所有这些都产生了 PHP 致命错误,说明与 Table class 有关 - 我怀疑这是否正确。
"moving out" 有点棘手,你必须明白在内部条件被推入一个 \Cake\Database\Expression\QueryExpression
对象,默认情况下使用 AND
连接语句,所以无论你继续下去,将使用 AND
.
当您创建 OR
语句时,无论是隐含地使用所示的嵌套数组语法,还是显式地使用表达式生成器,这都会创建一个单独的、自包含的表达式,其中其部分使用OR
,它将自行编译(因为只有一个条件,你看不到任何 OR
),结果将用于父表达式,在你的情况下是main/base 查询 where 子句的表达式对象。
一次传递整个东西(通过数组语法或表达式),例如:
$groups_data->where([
'OR' => [
'AND' => [
'regulation_id' => 1,
'label LIKE' => '%labelling%'
],
'id IN' => $in_array
]
]);
当然,如果需要,您可以动态构建该数组,或者,如果您出于某种原因需要单独调用 where()
,例如,您可以覆盖条件([=18 的第三个参数=]),并在您需要的地方包括当前的:
$groups_data->where(
[
'OR' => [
$groups_data->clause('where'),
'id IN' => $in_array
]
],
[],
true
);
我知道这个问题已经过时了,但也许有人正在寻找。这是我的解决方案:
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);
}
}
自 CakePHP 4.x 起,记录在案的执行此操作的方法是:
$query = $articles->find()
->where([
'author_id' => 3,
'OR' => [['view_count' => 2], ['view_count' => 3]],
]);