業務需求:接口返回一個列表,但是這個列表要求按一定的條件排序,條件如下:
1,某字段(field1)為null的排前面
2,某字段(field2)為null的排前面
3,姓名(field3)按照漢字的拼音排序
4,某字段(field4)按照ID倒序排序
乍一聽有點復雜,其他的不多說,這篇文章主要講怎么在TP5里實現按照漢字的拼音排序
多字段排序這里要介紹到TP5 一個類 想了解的可以參考這篇文章《TP5多字段排序》
查閱了資料,網上千篇一律,總結了兩點:
1,如果存儲姓名的字段采用的是GBK字符集,那就好辦了,因為GBK內碼編碼時本身就采用了拼音排序的方法(常用一級漢字3755個采用拼音排序,二級漢字就不是了,但考慮到人名等都是常用漢字,因此只是針對一級漢字能正確排序也夠用了),直接在查詢語句后面 添加 order by name asc; 查詢結果按照姓氏的升序排序;
2,如果存儲姓名的字段采用的是 utf8字符集,需要在排序的時候對字段進行轉碼;對於的代碼是 order by convert(name using gbk) asc; 同樣,查詢的結果也是按照姓氏的升序排序;
我相信大多數人用的應該是用的utf8字符集,所以這里就使用第二種方法
但是在TP中,如果使用不當,就會報錯
正確的寫法應該使用這篇文章《TP5多字段排序》中的方法,TP中的一個類,超級簡單超級好用。
//實例化這個類,並在實例化的時候傳入你需要的排序規則 $exp = new Expression('field(table1.field1,null),field(table2.field2,null),convert(table3.field3 using gbk) asc,table4.field4 desc');
//這里是示例代碼,具體需要根據自己的業務邏輯進行修改 $list = Model::join('table2 t2', 't1.id = t2.id','LEFT') ->join('table3 t3', 't1.id = t3.id','LEFT') ->join('table4 t4','t4.id = t3.id') ->field('你需要的字段') ->orderRaw($exp) ->with(['這里我進行了關聯關系查詢,不需要的可以用寫'])->where('查詢條件');
這樣多字段排序就完成了,不知道有沒有人注意到
我並沒有使用order,而是使用了orderRaw,為什么呢?我們來看看官方文檔
當你的order排序中使用了SQL函數的時候,請使用orderRaw
方法替代order
然后我們來看看查詢的效果,結果顯而易見,成功的按照漢字的拼音排序
如果想到倒序,你只需要在實例化的時候把asc改為desc即可。
總之,個人覺得這個方法非常好用,所以在這里記錄下來,歡迎留言學習交流。