sql - 如何在 SQL 中按数字排序?
问题描述
我遇到了一个问题,即按照 SQL 中的列数据中的数字进行排序。例如,列数据包括 100-1/1/1 ABC、100-1/1/3 CDE、100-1/1/2 CDE。我想按订单号结果排序,如 100-1/1/1 ABC ,100-1/1/2 CDE 和 100-1/1/3 CDE。
以下是示例表数据,表名称为test2
:
id | name |
4 200 DAVID
1 100 JOHN
3 100-1 SHAWN
9 100-1/1 PETER
11 100-1/1/1 ALVIS
12 100-1/1/10 ROBERT
2 100-1/1/11 HENRY
13 100-1/1/3 PIRES
14 100-2 CRISTY
20 100-1/2 BILLY
32 100-1/2/1 JIOUS
我用的是 MySQL 版本,写的 SQL 查询是SELECT * FROM test2 order by name
,但是不能正确排序。
实际上我希望预期的结果如下表所示:
id | name |
1 100 JOHN
3 100-1 SHAWN
9 100-1/1 PETER
11 100-1/1/1 ALVIS
13 100-1/1/3 PIRES
12 100-1/1/10 ROBERT
2 100-1/1/11 HENRY
20 100-1/2 BILLY
32 100-1/2/1 JIOUS
14 100-2 CRISTY
4 200 DAVID
这是我对名称进行排序的真实场景:
希望有人能指导我解决这个问题。谢谢。
解决方案
我不是使用正则表达式的专家,但是使用基本的表达式我们可以实现它,如下所示,
with cte as
(
select '200 DAVID' name
union all
select '100 JOHN'
union all
select '100-1 SHAWN'
union all
select '100-1/1 PETER'
union all
select '100-1/1/1 ALVIS'
union all
select '100-1/1/3 PIRES'
union all
select '100-1/1/10 ROBERT'
union all
select '100-1/1/11 HENRY'
union all
select '100-1/2 BILLY'
union all
select '100-1/2/1 JIOUS'
)
select *
from(select t.*,cast(regexp_substr(name,'[0-9]+') as unsigned) col1
,cast(regexp_substr(name,'[0-9]+',1,2) as unsigned) col2
,cast(regexp_substr(name,'[0-9]+',1,3) as unsigned) col3
,cast(regexp_substr(name,'[0-9]+',1,4) as unsigned) col4
from cte t) c
order by col1,col2,col3,col4
首先,我们从字符串中提取排序所需的数字,使用regexp_substr(name,'[0-9]+')
它匹配第一个数字一个字符并返回第一个匹配项,regexp_substr(name,'[0-9]+',1,2)
第二个匹配项从另一个数字字符匹配等等......然后在按子句排序。
编辑:- MYSQL 旧版本的解决方案
select t.id,t.name
from
(
select t.*, cast((case when col1_col2_ref > 0
then
substring_index(modified_name,'-',1)
else
modified_name
end) as unsigned) col1
, cast((case when col1_col2_ref > 0
and col3_ref > 0
then
substr(modified_name,(col1_col2_ref + 1),(col3_ref - (col1_col2_ref + 1)))
when col1_col2_ref > 0
then
substr(modified_name,(col1_col2_ref + 1))
end) as unsigned) col2
, cast((case when col3_ref > 0
and col4_ref > 0
then
substr(modified_name,(col3_ref + 1),(col4_ref - (col3_ref + 1)))
when col3_ref > 0
then
substr(modified_name,(col3_ref + 1))
end) as unsigned) col3
, cast((case when col4_ref > 0
then
substr(modified_name,(col4_ref + 1))
end) as unsigned) col4
from
(
select t.*,substring_index(name,' ',1) modified_name
,locate('-',name,1) col1_col2_ref
,locate('/',name,1) col3_ref
,locate('/',name,locate('/',name,1)+1) col4_ref
from test t
) t
) t
order by col1,col2,col3,col4
推荐阅读
- php - 页面延迟滚动不起作用,无法找出代码中的问题
- angular - Angular 6中使用行为主题的通知服务弹出窗口
- android - Android Studio 想要访问麦克风
- javascript - Scala.js:CSS 风格的控制台日志
- excel - 如果单元格包含某个字符串,则删除表格行
- c# - 是否有可能在 WPF 中设计一个具有翻转动画的 UI,就像在 windows phone 中一样?
- datatables - 下载选定的行
- redux - NGXS state size and performance
- python - 来自 Celery worker 的 scikit-learn 多处理
- excel - 从单元格中检索比较运算符