【问题标题】:I need to do a Custom Oracle Sort我需要进行自定义 Oracle 排序
【发布时间】:2018-04-12 21:54:32
【问题描述】:

如果这是一个简单的问题,我很抱歉。但是,我已经在大约一个小时内到处寻找答案。

我有一个 db_table,我需要对其进行排序以输出到网页中的表格。数据以如下方式存储在db_table中:

   date          Area         Value
   ------        ------      -------
 11-mar-18        middle        10
 11-mar-18        bottom         5
 11-mar-18        top           12

 12-mar-18        top           14
 12-mar-18        bottom         4
 12-mar-18        middle        17

问题是:如何对它们进行排序以产生以下结果:

    date          Area         Value
   ------        ------      -------
 11-mar-18        top           12 
 11-mar-18        middle        10
 11-mar-18        bottom         5 

 12-mar-18        top           14
 12-mar-18        middle        17
 12-mar-18        bottom         4

非常感谢任何帮助。

【问题讨论】:

    标签: sql oracle sql-order-by


    【解决方案1】:

    按字母顺序对区域进行排序,作为order by的第二个组成部分:

    select *
      from db_table
     order by "date", area desc;
    

    正如您提到的,如果 area 具有值 A、B、C、D 并且它们希望按 C、B、D、A 的顺序排序,则使用:

    select *
      from db_table
     order by "date", decode(area,'C',1,'B',2,'D',3,'A',4);
    

    附:特别是,我将日期列放在引号内,因为已经创建了带有 "date" 列的表,而不是作为关键字的 date

    【讨论】:

    • 对不起,我忘了提一个方面。例如,如果区域列中的选项是 A、B、C、D 并且我想按日期排序然后将区域排序为 C、B、D、A 怎么办?
    • 按“日期”排序, decode(area,'C',1,'B',2,'D',3,'A',4)
    • 最好在所有情况下使用decode(或case),而不是利用TOP、MIDDLE和BOTTOM的字典顺序正好相反的意外。有一天,它们将更改为 FIRST、MIDDLE、LAST,并且查询将不再给出正确的顺序。最好强迫他们对ORDER BY 进行必要的更改,如果他们做过类似的事情的话。
    【解决方案2】:
    select *
      from db_table
     order by "date", 
        case 
           when area = 'top' then 1 
           when area = 'middle' then 2
           when area = 'bottom' then 3
           else 4
        end;
    

    参考Custom Sort Order

    【讨论】:

    • "Simple" case 表达式效果更好:case area when 'top' then 1 when 'middle' then 2 when 'bottom' then 3 end 另请注意,如果您省略 else 4,则默认为 else null - 对排序具有相同的效果。你真的不需要else 部分。
    • @mathguy,如果没有else 4,则为 null 或除 top、middle 或 bottom 之外的值的区域将首先出现。可能那很好。 else 4 将它们放在每组的末尾。 OP 必须做出决定。
    • 没有。如果没有else 4case 表达式将为除顶部、中间或底部之外的行返回 null,并且 nullorder by 中出现在最后(默认情况下 - 如果未明确要求首先出现)。您似乎对此不熟悉,因此它将帮助您为自己编写一个非常小的示例并运行它。你会明白我的意思。
    • @mathguy 你是对的。我在 mysql 而不是 oracle 中测试。
    • MySQL 有什么不同? case 的“else null”默认值和排序的“nulls last”默认值都在 SQL 标准中。
    【解决方案3】:

    instr() 在大多数情况下提供比case 更短的解决方案:

    select t.*
    from t
    order by t.date, instr('top,middle,bottom', area)
    

    【讨论】:

    • 呃...如果按此顺序排序的值是 stop、top 和 op 怎么办?任何认真的程序员都不应该使用这样的技巧。如果您发现 case 过于冗长,请使用 decode
    • @mathguy 。 . .值是固定的。在大多数情况下,这是一个完全合理的解决方案。
    • @GordonLinoff,谢谢,这有助于我对尺寸进行排序,我使用了 INSTR('XS,S,M,L,XL,XXL', size_cd, 1) 并且它有效。这个技巧对我来说真的很有帮助。
    猜你喜欢
    • 2011-07-31
    • 1970-01-01
    • 2021-07-25
    • 2019-12-25
    • 1970-01-01
    • 1970-01-01
    • 2018-01-17
    • 2013-01-06
    • 1970-01-01
    相关资源
    最近更新 更多