CakePHP 3.x中MySQL CASE排序异常及多排序需求问询
解决CakePHP 3.x中CASE语句排序的方向问题及多条件排序
嘿,这个问题我之前也碰到过!其实这不是CakePHP的限制,只是咱们需要明确给CASE表达式指定排序方向,同时添加第二个排序条件也很简单,我给你两种可行的方案:
方案一:给CASE表达式链式调用排序方法
你可以直接在addCase()返回的表达式后面调用desc()(或者asc())来指定排序方向,然后用order()方法追加第二个排序规则:
$articles = $this->Articles->find() ->where($conditions) ->order(function ($exp, $q) { return $exp->addCase( [ // 匹配条件:文章在过去365天内更新过 $q->newExpr()->gt('Articles.modified', (new Time())->subDays(365)) ], ['priority'], // 匹配成功时的取值 ['string'] // 值的类型 )->desc(); // 这里指定CASE表达式的排序方向为降序 }) ->order(['Articles.publish' => 'DESC']) // 追加第二个排序规则:按publish字段降序 ->limit(15) ->all();
方案二:用数组形式统一定义排序规则
如果你更喜欢把所有排序规则放在一个order()调用里,可以用数组形式,给CASE表达式对应的键指定排序方向:
$articles = $this->Articles->find() ->where($conditions) ->order([ function ($exp, $q) { return $exp->addCase( [ $q->newExpr()->gt('Articles.modified', (new Time())->subDays(365)) ], ['priority'], ['string'] ); } => 'DESC', // 给CASE表达式指定降序 'Articles.publish' => 'DESC' // 第二个排序条件 ]) ->limit(15) ->all();
这两种方案最终生成的SQL都会符合你的需求,类似这样:
SELECT
Articles.idASArticles__id, .... FROMarticlesArticlesWHERE (publish< :c0 ANDArticles.publish> :c1) ORDER BY CASE WHENArticles.modified> :c2 THEN :param3 END DESC,Articles.publishDESC LIMIT 15
简单来说,addCase()只是负责生成CASE逻辑的表达式部分,排序方向需要我们额外声明,这样就完全满足你的排序需求啦~
内容的提问来源于stack exchange,提问作者Alan A
相关产品推荐
相关产品推荐

