我有一个带有字段 name 的表,该字段不仅包含文本,还包含数字。我按名称排序:
->orderBy(['name' => SORT_ASC])
...
阿尔塔穆拉 7
阿尔塔穆拉 8
安塞多尼亚 1
安塞多尼亚10
安塞多尼亚 11
安塞多尼亚 12
安塞多尼亚2
安塞多尼亚 3
...
安塞多尼亚 9
但我希望列表不仅按字母顺序排序,还按名称中的数字排序:
...
阿尔塔穆拉 7
阿尔塔穆拉 8
安塞多尼亚 1
安塞多尼亚2
安塞多尼亚 3
...
安塞多尼亚 9
安塞多尼亚 10
安塞多尼亚 11
安塞多尼亚 12
如果可以的话
是的,这是可能的。为此,您需要使用一种非常特殊的排序方式,称为“自然排序”。 SQL 本质上不包含自然排序,但我们可以模拟它。例如,在 MySQL 中,您可以使用 CONVERT(column, UNSIGNED INTEGER) 对混合字符串/整数字段进行排序。此隐式转换提取数字部分并将其作为数字排序。 以下是您的情况的示例:
->orderBy([
new \yii\db\Expression('CAST(SUBSTRING_INDEX(name, " ", -1) AS UNSIGNED)'),
'name' => SORT_ASC
])
对于 PostgreSQL,您可以使用正则表达式来模拟自然排序来分隔字段的数字部分。 您可以这样做:
->orderBy([
new \yii\db\Expression("substring(name, '^[a-zA-Z]+')"),
new \yii\db\Expression("CAST(substring(name, '[0-9]+$') AS INTEGER)"),
])