2017-04-27 84 views
1

我很困惑,是我一直在CakePHP的3文檔查詢生成器的高級閱讀條件:https://book.cakephp.org/3.0/en/orm/query-builder.html#advanced-conditions在CakePHP 3中,Where(),Where(),where()方法的順序是什麼?

它提供了以下代碼

$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])是last i PHP首先在SQL語句中。爲什麼?)。

,可能是相關的文檔中的唯一信息是這樣說的:

每種方法設置當前和 以前的狀態之間所使用的合併算。

這是文檔中的錯誤,還是有人可以解釋這是如何以更好的方式真正起作用?

雖然我明白,這幾乎可以肯定是錯誤的,我的是SQL如何評估的理解是:

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

@JasonJoslin我不認爲你真的明白這個問題。你提供了一個基於字母順序的答案(並且隨後將其刪除,因爲它是垃圾)。這與查詢中出現OR或AND條件的順序有關 - 這非常影響查詢結果,並且肯定不會產生相同的結果,除非生成的查詢總是一致的的PHP條件。 – Andy

回答

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(); 
+2

事情可能有點令人困惑......兩者都和'()'和'orWhere()'將採取現有的條件堆棧並將它們與新聞條件相結合。然而'orWhere()'似乎表現出的行爲與預期的不同(記錄在案),也就是說,它會預先給出新的條件,而'和()'附加它們。這不會改變邏輯,但它肯定會增加混亂。 – ndm

+1

** https://github.com/cakephp/cakephp/pull/10591** – ndm