Oracle SQL:具有窗口聚合函数的自定义ORDER BY子句

时间:2014-04-08 15:44:15

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

我正在努力整理一个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 =冬季),最后一位数应该被忽略(出于比较原因)。 / p>

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

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

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

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

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

1 个答案:

答案 0 :(得分:2)

您可以使用解码或案例陈述来动态“修复”季节排序。 (你没有'春天'?)

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