在Oracle SQL中对字母数字列进行排序

时间:2018-09-13 02:28:37

标签: sql oracle sorting oracle11g sql-order-by

我不是SQL专家。我一直在谷歌搜索下面如何实现。 我需要根据ID对记录进行排序。 (首先是前缀,然后是它们的数值)

Table: CUSTOMER_TRANS

| ID       | Name   | Date       |
|==========|========|============|
|CP-091435 | Ola    | 01-01-2010 |
|WM-183258 | Tor    | 09-09-2001 |
|CP-109056 | Jess   | 03-03-2003 |


SELECT * FROM CUSTOMER_TRANS ORDER BY substr(ID, 4) desc;

我需要先对2个前缀进行排序,例如ES,然后对数值进行排序。 但是,我上面的SQL仅返回数字最高的WM-183258。 预期的结果是首先返回“ CP”前缀,并返回最高的数值,例如下面。希望有人可以给我一些启发。

预期结果:

| ID       | Name   |
|==========|========|
|CP-109056 | Ola    | 
|CP-091435 | Jess   | 
|WM-183258 | Tor    | 

3 个答案:

答案 0 :(得分:2)

我的PL / SQL很生锈,但是您应该可以使用

... ORDER BY substr(ID, 1, 2) ASC, substr(ID, 4) DESC

,甚至由mathguy指出的更好

... ORDER BY substr(ID, 1, 2) ASC, ID DESC

也就是说,按照前两个字符升序排列,然后其余的降序排列。


从性能角度来看,这可能不是很理想。我会考虑将ID分解成各个部分,例如

ID_PREFIX CHAR(2),
ID_SUFFIX CHAR(6) -- or a numeric type, whatever is appropriate

并在两者上创建主键。这样可以很容易地进行分组和排序,并进行显示,您只需使用

SELECT ID_PREFIX || '-' || ID_SUFFIX AS ID...

答案 1 :(得分:1)

您可以尝试this one

with CUSTOMER_TRANS(Id,Name) as
(
 select 'CP-091435','Ola' from dual union all    
 select 'WM-183258','Tor' from dual union all
 select 'CP-109056','Jess' from dual   
)
select *
  from CUSTOMER_TRANS
 order by substr(ID, 1, 2), substr(ID,4,length(ID)) desc;

| ID       | Name   |
|==========|========|
|CP-109056 | Jess   | 
|CP-091435 | Ola    | 
|WM-183258 | Tor    | 

答案 2 :(得分:0)

我认为使下一个人可以理解代码的最佳方法是使用虚拟列

scatter()

然后您可以“按前缀排序,后缀desc