【问题标题】:Oracle SQL: Custom ORDER BY clause with a window aggregate functionOracle SQL:具有窗口聚合函数的自定义 ORDER BY 子句
【发布时间】:2014-04-08 15:44:14
【问题描述】:

我正在整理一个 Oracle SQL 语句,该语句可以执行我需要的一些高级排序。到目前为止,这是我的声明:

SELECT TIME, PLACE
FROM TABLENAME
ORDER BY MIN(year) OVER (PARTITION BY PLACE), PLACE, TIME;

在获得其他问题 (Oracle SQL Grouping/Ordering) 的帮助后,我将其放在一起。现在我需要将季节加入其中,但是,它们在现有数据库中没有数字编号。

假设我有以下数据

TIME   | PLACE
198410 | somewhere
198320 | work
198431 | somewhere
198232 | home
198322 | work
198211 | home
198422 | somewhere

TIME 列的前四位数字是年份,下一个数字是季节(其中 2 = 夏季,3 = 秋季,1 = 冬季),最后一个数字应忽略(出于比较原因)。

上述查询将产生以下结果(将地点组合在一起并根据时间(数字)对它们进行排序):

TIME   | PLACE
198410 | somewhere
198422 | somewhere
198431 | somewhere
198320 | work
198322 | work
198211 | home
198232 | home

但是,我需要一个将奇怪编码的季节(夏季 = 2、秋季 = 3、冬季 = 1)考虑在内并产生以下按时间顺序排序的结果的查询:

TIME   | PLACE
198422 | somewhere
198431 | somewhere
198410 | somewhere
198320 | work
198322 | work
198232 | home
198211 | home

我没有制定这个标准,但不幸的是我必须遵守它。非常感谢任何有关解决此问题的帮助。

【问题讨论】:

    标签: sql oracle sorting sql-order-by aggregate-functions


    【解决方案1】:

    您可以使用 decode 或 case 语句即时“修复”季节排序。 (你没有'弹簧'?)

    select time, place
    from tablename
    order by max(substr(time, 1, 4) || case substr(time, 5, 1)
          when '2' then 1 when '3' then 2 when '1' then 3 end)
        over (partition by place) desc,
      place,
      substr(time, 1, 4) desc,
      case substr(time, 5, 1) when '2' then 1 when '3' then 2 when '1' then 3 end;
    

    您似乎按代码示例未执行的降序排列年份,但这与您想要的输出相匹配:

    TIME   PLACE   
    ------ ---------
    198422 somewhere 
    198431 somewhere 
    198410 somewhere 
    198320 work      
    198322 work      
    198232 home      
    198211 home      
    

    SQL Fiddle.

    当您重复年份提取和调整季节计算时,您可能更愿意在子查询中处理一次:

    select time, place
    from (
      select time, place, substr(time, 1, 4) as year,
        case substr(time, 5, 1) when '2' then 1 when '3' then 2 when '1' then 3 end
          as season
      from tablename
    )
    order by max(year || season) over (partition by place) desc,
      place, year desc, season;
    

    Another SQL Fiddle.

    【讨论】:

    • 看起来不错,但如果 TIME 列是数字数据类型,这将不起作用。
    • @user2989408 - it would,会隐式转换为字符串,并得到相同的结果;至少只要所有数字的位数相同。
    • +1 不知道SUBSTR 将参数隐式转换为字符串。
    • 在计算语句第 3 行的最大值时会考虑季节吗?好像不会。是否有可能改变这一点?
    • @HarryMuscle - 当然,我已将其更改为在分析函数中重复 case,将其结果连接到年份并按其排序。我最初有它,并认为它不需要,但你是对的。您可能会发现在子查询中拆分年份和调整后的季节更容易,因此您无需重复操作,但这取决于我认为的实际用例。
    猜你喜欢
    • 2022-08-17
    • 1970-01-01
    • 1970-01-01
    • 2017-12-22
    • 2012-12-07
    • 1970-01-01
    • 2019-04-23
    • 2010-11-15
    • 1970-01-01
    相关资源
    最近更新 更多