简体   繁体   English

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

[英]Sort Alphanumeric column in Oracle SQL

I am not an SQL expert. 我不是SQL专家。 I've been searching over google on how to achieve below. 我一直在谷歌搜索下面如何实现。 I need to sort my records based on ID. 我需要根据ID对记录进行排序。 (prefix first and then their numerical values) (首先是前缀,然后是它们的数值)

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;

I need to sort first the 2 prefix eg ES and then the numerical values. 我需要先对2个前缀进行排序,例如ES,然后对数值进行排序。 However, my SQL above returns only the numerical highest WM-183258. 但是,我上面的SQL仅返回数字最高的WM-183258。 The expected result is to returns first the "CP" prefix and the highest in numerical value eg below. 预期的结果是首先返回“ CP”前缀,然后返回最高数值,例如下面的数值。 Hope someone can give me somelight. 希望有人可以给我一些启发。

Expected Result: 预期结果:

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

My PL/SQL is quite rusty but you should be able to use something like 我的PL / SQL很生锈,但是您应该可以使用类似

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

or even better as pointed out by mathguy 甚至比Mathguy指出的更好

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

That is, sort by the first two characters ascending, then by the rest descending. 也就是说,按前两个字符升序排序,然后按其余的降序排序。


That's probably quite sub-optimal from a performance perspective. 从性能的角度来看,这可能不是很理想。 I would consider breaking up that ID into it's parts, eg 我会考虑将该ID分解为各个部分,例如

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

and create your primary key on both. 并在两者上创建您的主键。 That makes it easy to group and sort and for display, you can just use 这样可以很容易地进行分组和排序以及显示,您只需使用

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

You may try 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    | 

I think the best way to make the code understandable the next person is to use virtual columns 我认为让下一个人可以理解代码的最佳方法是使用虚拟列

Alter table CUSTOMER_TRANS add(prefix generated always as (substr(longid,1,2)) virtual,
                     suffix generated always as (substr(longid,4)) virtual);

Then you can just "Order by prefix, suffix desc 然后,您可以“按前缀排序,后缀desc

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM