【问题标题】:What order are andWhere(), orWhere(), where() methods evaluated in CakePHP 3?在 CakePHP 3 中评估的 andWhere()、orWhere()、where() 方法的顺序是什么?
【发布时间】:2023-03-27 11:09:01
【问题描述】:

我对我在 CakePHP 3 文档 Query Builder's Advanced Conditions 上读到的内容感到困惑:https://book.cakephp.org/3.0/en/orm/query-builder.html#advanced-conditions

它给出了以下代码

$query = $articles->find()
->where(['author_id' => 2])
->orWhere(['author_id' => 3])
->andWhere([
    'published' => true,
    'view_count >' => 10
])
->orWhere(['promoted' => true]);

并且说这等价于这条 SQL:

SELECT *
FROM articles
WHERE (promoted = true
OR (
  (published = true AND view_count > 10)
  AND (author_id = 2 OR author_id = 3)
))

我根本不了解它是如何工作的,因为 PHP 中条件的顺序与生成的 SQL 语句中的顺序不同(例如,->orWhere(['promoted' => true]) 在 PHP 中是最后一个,但在SQL 语句。为什么?)。

文档中唯一可能相关的信息是它所说的:

每个方法都设置当前和当前使用的组合运算符 以前的条件。

这是文档中的错误,还是有人可以解释它如何以更好的方式真正起作用?

虽然我意识到这几乎肯定是错误的,但我对该 SQL 将如何评估的理解是:

SELECT *
FROM articles
WHERE (author_id = 2 OR author_id = 3)
AND ( (published = true AND view_count > 10) OR promoted = true)

【问题讨论】:

  • @JasonJoslin 我不认为你真的理解这个问题。您根据字母顺序提供了一个答案(随后因为它是垃圾而将其删除)。这与查询中出现ORAND 条件的顺序有关——这对查询结果有很大影响,并且肯定不会产生相同的结果,除非生成的查询始终是给定一组特定的 PHP 条件。

标签: php mysql sql cakephp


【解决方案1】:

当您使用 orWhere 查询构建器时,它会占用整个 where 子句并将其放在 OR 运算符的一侧,这就是为什么它是这样的

WHERE (
   promoted = true
   OR 
   (
      (published = true AND view_count > 10)
      AND 
      (author_id = 2 OR author_id = 3)
   )
)

你必须这样写才能得到想要的输出

    $query = $this->Orders->find()
        ->where(['author_id' => 2])
        ->orWhere(['author_id' => 3])
        ->andWhere([
            'OR'=>[
                ['promoted' => true],
                ['published' => true,
                    'view_count >' => 10]
            ]
        ]);

     $query = $this->Orders->find()
            ->where(['author_id' => 2])
            ->orWhere(['author_id' => 3])
            ->andWhere(function (QueryExpression $exp) {
                return $exp->or_([
                    'promoted' => true,
                    ['published' => true,
                        'view_count >' => 10]
                ]);
            })->toArray();

【讨论】:

  • 事情可能有点令人困惑...andWhere()orWhere() 都将采用整个现有条件堆栈并将它们与新闻条件结合起来。但是另外orWhere() 的行为似乎与预期的不同(记录在案),即它将添加新条件,而andWhere() 会添加它们。这不会改变逻辑,但肯定会增加混乱。
猜你喜欢
  • 2015-11-02
  • 1970-01-01
  • 1970-01-01
  • 2010-09-18
  • 2021-02-14
  • 1970-01-01
  • 2023-03-03
相关资源
最近更新 更多