我有一个场景,其中一个字段包含字符和数字,我想按下面给出的排序。
City 1
City 2
City 3
City 4a
City 4b
City 4c
City 10
City 11a
City 11b
Town 1
Town 2
Town 3a
Town 4b
Town 10
该查询还应考虑到将来可以添加更多字段,例如100
,101a
等。
提前致谢。
答案 0 :(得分:1)
另一种可能的方法是使用正则表达式
下面是一个如何解析字符串并分成子字段的示例:
select col,
regexp_replace( col, '\D+\s+(\d+).*','\1') As field1,
regexp_replace( col, '\D+\s+\d+(\D*),*.*','\1') As field2,
regexp_replace( col, '\D+\s+\d+\D*,*(\d*)','\1') As field3
from table1
ORDER BY field1, field2, field3
;
如果只需要排序,则在ORDER BY子句中使用这些函数:
select * from table1
order by
regexp_replace( col, '\D+\s+(\d+).*','\1'),
regexp_replace( col, '\D+\s+\d+(\D*),*.*','\1'),
regexp_replace( col, '\D+\s+\d+\D*,*(\d*)','\1')
演示:http://sqlfiddle.com/#!4/8f289/4
但是对于大型数据集来说,这将是非常缓慢的
您需要规范化表中的数据 - 在插入期间解析它并将每个字段存储在表中的单独列中,然后在这些列上创建索引。
使用强制转换为数字的排序:
select col,
cast( regexp_replace( col, '\D+\s+(\d+).*','\1') as numeric) As field1,
regexp_replace( col, '\D+\s+\d+(\D*),*.*','\1') As field2,
cast( regexp_replace( col, '\D+\s+\d+\D*,*(\d*)','\1') As numeric) As field3
from table1
ORDER BY field1, field2, field3
;
select * from table1
order by
cast( regexp_replace( col, '\D+\s+(\d+).*','\1') as numeric),
regexp_replace( col, '\D+\s+\d+(\D*),*.*','\1'),
cast( regexp_replace( col, '\D+\s+\d+\D*,*(\d*)','\1') As numeric)
答案 1 :(得分:0)
怎么样:
order by SUBSTRING(col_name, CHARINDEX(' ', col_name) + 1, len(col_name)-(CHARINDEX(' ', col_name)-1))
这里SUBSTRING(col_name, from_index, till_index)
给我这些索引之间的子串,并使用CHARINDEX
函数我找到字符串第二个字周围的索引来提取它。
请注意,根据我的理解,这不会使用任何索引,如果表中有大量数据,可能会很慢。