【问题标题】:Sort Alphanumeric column in Oracle SQL在 Oracle SQL 中对字母数字列进行排序
【发布时间】:2019-02-17 17:22:41
【问题描述】:

我不是 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    | 

【问题讨论】:

  • 所以你需要按前缀升序和数字降序排序,对吗?
  • 如果我这样做,结果是 WM-183258 位于顶部。顶部的预期 ID 是 CP-109056(如第二张表所示)。 @菲尔
  • 是的,对不起。我没有正确阅读你的问题。为了清楚起见,我更新了我的评论
  • 是的,正确。我需要先将前缀排序为 asc,然后将数值排序为 desc。 @菲尔
  • 天啊!!!非常感谢@Phil。你救了我的一天..谢谢。像魅力一样工作! :)

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


【解决方案1】:

我的 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...

【讨论】:

  • 请注意,SUBSTR 将第一个字符视为位置 1,而不是 0。
  • @JeffreyKemp gah 愚蠢的甲骨文。谢谢,虽然显然零被视为与1
  • 没错; SUBSTR 从第一个字符开始计数,只要字符 >= 请求的起始位置就发出它 - 所以零也可以(只是冒着让来自其他背景的人感到困惑的风险)。
  • 请注意,在按字母片段排序后,按数字部分排序就等同于按整个字符串排序。也就是说,第二个排序表达式可以是ID 本身。这将节省每行一个函数调用。
【解决方案2】:

你可以试试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    | 

【讨论】:

    【解决方案3】:

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

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

    然后你可以只“按前缀排序,后缀desc”

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-19
      • 1970-01-01
      相关资源
      最近更新 更多