Laravel:按条件排序和筛选

42

我正在使用SphinxSearch查询某些内容,并具有要使用MySQL查询的对象的ID。我的ID数组根据Sphinx给出的排名进行排序。 因此,我想创建一个类似以下的MySQL查询:

SELECT * FROM table WHERE id IN (1,17,2) 
ORDER BY FIELD(id,1,17,2)

我知道我能做到:

Table::whereIn('id', $ids)->get();

但我无法获得我之前拥有的订单。

我该如何使用Laravel以恰当的方式实现?


1
看一下 orderByRaw - ceejayoz
3个回答

120

解决方案:

$ids = array(1,17,2);
 
$ids_ordered = implode(',', $ids);
 
$items = static::whereIn('id', $ids)
 ->orderByRaw("FIELD(id, $ids_ordered)")
 ->get();

附加说明:

使用在一篇名为使用Eloquent按照WHERE IN子句中ID的当前顺序一次性获取所有项目并排序的文章中找到的解决方案:

当您想通过在WHERE IN子句中提供的ID数组的顺序对数据库中的项目进行orderBy时,这将非常有用。可以轻松修改以适应您的需求,例如提供不同的ID顺序。

// Raw SQL:
// SELECT * FROM items WHERE id IN (1,2,3,4,5) ORDER BY FIELD(id,1,2,3,4,5);
 
$itemIds = array(1,2,3,4,5);
 
$ids = implode(',', $itemIds);
 
$items = static::whereIn('id', $itemIds)
    ->orderByRaw(DB::raw("FIELD(id, $ids)"))
    ->take($limit)
    ->get();

8
这是纯金。 - Valdrinium
$ids_ordered = implode(',', $itemIds); 翻译为 $ids_ordered = implode(',', $ids); - kunal
这只适用于MySQL。我不得不使用PHP进行排序,因为我使用的是Postgres。 - TheDevWay
正如原帖所述,这是一个关于MySQL的特定问题。您可以尝试使用类似于以下链接中的内容更改原始SQL:https://dev59.com/questions/iHNA5IYBdhLWcg3wrf83 - MPikkle
这太不可思议了! - James Shisiah
有没有Postgres版本?该数据库不支持FIELD。 - Riza Khan

9
我也遇到了这个问题,但是我的目标数组元素是字符串。在这种情况下...
$strings = array('xxx','yyy','zzz');

$imploded_strings = implode("','", $strings);

$items = static::whereIn('some_column', $strings)
->orderByRaw(DB::raw("FIELD(some_column, '$imploded_strings')"))
->get();

1
对我有效的方法是:$searchedStrings = "'".implode("', '", $originalArrayOfStrings)."'"; - Banik
你有适用于Postgres的版本吗?FIELD在其中不可用。 - Riza Khan
亲爱的Riza Khan,您可以在以下链接中了解更多关于Postgres这个功能的内容: https://dev59.com/xHM_5IYBdhLWcg3wmkUK - Mehdi hosein pour

-1
$category_id = Category::select('id')->orderby('name','ASC')->get()->pluck('id')->toArray();

像这样的长行通常受益于换行 :-) - halfer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接