[英]How to sort order by number in SQL?
I am facing a problem to sort order follow the number in the column data in SQL.我在按照 SQL 中列数据中的数字进行排序时遇到问题。 For example, the column data include are 100-1/1/1 ABC , 100-1/1/3 CDE, 100-1/1/2 CDE.例如,列数据包括 100-1/1/1 ABC 、100-1/1/3 CDE、100-1/1/2 CDE。 I want to sort in order number result follow like 100-1/1/1 ABC ,100-1/1/2 CDE and 100-1/1/3 CDE.我想按顺序编号结果进行排序,例如 100-1/1/1 ABC 、100-1/1/2 CDE 和 100-1/1/3 CDE。
Below is sample table data, table name called test2
:下面是示例表数据,表名为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
I am using MySQL version, and write the SQL query is SELECT * FROM test2 order by name
, but it cannot sort the number correctly.我使用的是 MySQL 版本,编写的 SQL 查询是SELECT * FROM test2 order by name
,但它无法正确排序数字。
Actually I want the expected result is like below the table:其实我希望预期的结果如下表所示:
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
This is my real scenario for sort the name:这是我对名称进行排序的真实场景:
Hope someone can guide me to solve this problem.希望有人能指导我解决这个问题。 Thanks.谢谢。
I am no expert in using regular expression , however using basic one we could achieve it as bellow,我不是使用正则表达式的专家,但是使用基本的我们可以如下实现它,
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
First we extract the numeric required for ordering from the string using regexp_substr(name,'[0-9]+')
which matches first numeric one more character and returns the first occurrence and with regexp_substr(name,'[0-9]+',1,2)
the second occurrence from one more numeric character match and so on...... and then use accordingly in the order by clause.首先,我们使用regexp_substr(name,'[0-9]+')
从字符串中提取排序所需的数字,该数字与第一个数字再匹配一个字符并返回第一次出现,使用regexp_substr(name,'[0-9]+',1,2)
第二次出现从另一个数字字符匹配等等......然后在 order by 子句中相应地使用。
Edit:- Solution for MYSQL older versions编辑:- 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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.