我有这段代码。
$array= $this->morphMany
('App\Models\Asset', 'assigned', 'assigned_type', 'assigned_to')
->withTrashed()
->orderByRaw('LENGTH(name)', 'ASC')->orderBy('name', 'ASC');
我用它来对带有字母数字字符的字符串进行自然搜索,因为使用字母搜索会导致奇怪的排序,例如
产品1
product10
产品2
product20
它似乎完美无缺。
我对此有几个问题,主要是orderBy中使用的算法是什么?两者的结合如何最终给我一个自然的秩序?我知道长度检查和字母检查的组合是解决方案,但这如何在laravel中工作?是否有一个特定的排序算法,如合并排序?我不明白它如何优先于一种优先于另一种。
我是laravel的新手。感谢。
答案 0 :(得分:1)
问题是:item123
会出现在词典中的item2
之前。为了克服这个问题,你要说"只有当项目具有相同的长度时才根据字典排序,否则较短的项目首先出现"。通过这些规则组合,你得到:
item2
出现在item11
之前,因为它更短(ORDER BY LENGTH(name)
优先)
item123
出现在item234
之前,因为它在字典中位于它之前(Items具有相同的长度,因此它们按其值排序)
现在MySQL用于排序的算法并不重要,但它足以让人知道它针对大型数据集的速度和排序数据进行了优化。重要的是每种排序算法使用compare
函数来比较两个值并确定它们的顺序。
MySQL根据您的ORDER BY
语句及其自己的内部比较规则构造此函数。例如:ORDER BY LENGTH(name), name
可能会导致比较如下:
compare(x,y)
if (default_comparer(LENGTH(x.name),LENGTH(y.name)) == 0) {
return default_comparer(x.name,y.name);
} else {
return default_comparer(LENGTH(x.name),LENGTH(y.name));
}
其中default_comparer
将是MySQL使用的默认内部比较器的模拟名称(在字符串的情况下)会考虑很多事情,如字母顺序,区域设置,案例规则等。现实MySQL可能有一个通用比较器,然后遍历每个order by语句以获得第一个非零结果返回)。
这有点模糊,我不是MySQL开发人员所以我无法提供更准确的信息,但这是它的工作原理的粗略图像。
答案 1 :(得分:0)
这与Laravel无关,您的数据库决定如何完成订购。
通常,当有两个或更多ORDER
个语句时,结果首先按第一个语句排序。如果有一些元素对第一个订单语句具有相同的值,则这些元素按二阶语句排序,依此类推。