【问题标题】:MAX analytic function with date window preserving time具有日期窗口保留时间的 MAX 分析函数
【发布时间】:2016-11-14 11:11:12
【问题描述】:

我正在尝试在前一行的窗口中获取最大日期。值得注意的是日期的实际时间部分。

实际的表包含更多日期的数据,但查询驻留在一个函数中,该函数将日期作为参数以将数据限制为一天。

+---------------------------------------------------------------------+
¦FROM  ¦ TO    ¦ GRAPH                                                ¦
+------+-------+------------------------------------------------------¦
¦09:00 ¦ 11:00 ¦  [--------]                                          ¦
¦10:00 ¦ 10:30 ¦     [-]                                              ¦
¦10:45 ¦ 12:00 ¦         [-------]                                    ¦
¦13:00 ¦ 14:30 ¦                      [--------]                      ¦
¦14:00 ¦ 15:00 ¦                            [-----]                   ¦
¦15:30 ¦ 16:30 ¦                                      [----]          ¦
¦16:30 ¦ 17:30 ¦                                           [-----]    ¦
+---------------------------------------------------------------------+
-- show the time portion when querying, for convenience
alter session set nls_date_format = 'DD/MM/YYYY HH24:MI';

-- create an inline view with some data, perform select on it
with iv_dates (start_dt, end_dt) as ( 
select to_date('08/07/2016 09:00','DD/MM/YYYY HH24:MI'), to_date('08/07/2016 11:00','DD/MM/YYYY HH24:MI') from dual 
union all 
select to_date('08/07/2016 10:00','DD/MM/YYYY HH24:MI'), to_date('08/07/2016 10:30','DD/MM/YYYY HH24:MI') from dual 
union all 
select to_date('08/07/2016 10:30','DD/MM/YYYY HH24:MI'), to_date('08/07/2016 12:00','DD/MM/YYYY HH24:MI') from dual 
union all 
select to_date('08/07/2016 13:00','DD/MM/YYYY HH24:MI'), to_date('08/07/2016 14:30','DD/MM/YYYY HH24:MI') from dual 
union all 
select to_date('08/07/2016 14:00','DD/MM/YYYY HH24:MI'), to_date('08/07/2016 15:00','DD/MM/YYYY HH24:MI') from dual 
union all 
select to_date('08/07/2016 15:30','DD/MM/YYYY HH24:MI'), to_date('08/07/2016 16:30','DD/MM/YYYY HH24:MI') from dual 
union all 
select to_date('08/07/2016 16:30','DD/MM/YYYY HH24:MI'), to_date('08/07/2016 17:30','DD/MM/YYYY HH24:MI') from dual 
) 
 SELECT start_dt 
      , end_dt 
      , MAX (end_dt) OVER ( ORDER BY start_dt asc 
                            RANGE BETWEEN UNBOUNDED PRECEDING 
                            AND     1     PRECEDING 
                          )  
                          max_end_dt
 FROM iv_dates;

但是,我没有得到 max end_dt 的任何结果...

+--------------------------------------------------+
¦ START_DT         ¦ END_DT           ¦ MAX_END_DT ¦
+------------------+------------------+------------¦
¦ 08/07/2016 09:00 ¦ 08/07/2016 11:00 ¦ -          ¦
¦ 08/07/2016 10:00 ¦ 08/07/2016 10:30 ¦ -          ¦
¦ 08/07/2016 10:30 ¦ 08/07/2016 12:00 ¦ -          ¦
¦ 08/07/2016 13:00 ¦ 08/07/2016 14:30 ¦ -          ¦
¦ 08/07/2016 14:00 ¦ 08/07/2016 15:00 ¦ -          ¦
¦ 08/07/2016 15:30 ¦ 08/07/2016 16:30 ¦ -          ¦
¦ 08/07/2016 16:30 ¦ 08/07/2016 17:30 ¦ -          ¦
+--------------------------------------------------+

虽然只要我添加另一天的日期,它就会开始“工作”

+--------------------------------------------------------+
¦ START_DT         ¦ END_DT           ¦ MAX_END_DT       ¦
+------------------+------------------+------------------¦
¦ 08/07/2016 09:00 ¦ 08/07/2016 11:00 ¦ -                ¦
¦ 08/07/2016 10:00 ¦ 08/07/2016 10:30 ¦ -                ¦
¦ 08/07/2016 10:30 ¦ 08/07/2016 12:00 ¦ -                ¦
¦ 08/07/2016 13:00 ¦ 08/07/2016 14:30 ¦ -                ¦
¦ 08/07/2016 14:00 ¦ 08/07/2016 15:00 ¦ -                ¦
¦ 08/07/2016 15:30 ¦ 08/07/2016 16:30 ¦ -                ¦
¦ 08/07/2016 16:30 ¦ 08/07/2016 17:30 ¦ -                ¦
¦ 09/07/2016 09:00 ¦ 09/07/2016 11:00 ¦ 08/07/2016 11:00 ¦
¦ 09/07/2016 10:00 ¦ 09/07/2016 10:30 ¦ 08/07/2016 11:00 ¦
¦ 09/07/2016 10:30 ¦ 09/07/2016 12:00 ¦ 08/07/2016 12:00 ¦
+--------------------------------------------------------+

只是为了说明这一点 - 我不需要分区,我只是希望它在我的数据上工作一天。

但似乎由于日期数据类型,窗口子句的行为有所不同。我不希望这样 - 我只希望它根据排序在实际的前一行上工作,而不是在 (date - 1) 上工作。是不是因为这是约会,我该如何处理?

【问题讨论】:

  • 我认为您正在寻找 ROWS BETWEEN 而不是 RANGE BETWEEN
  • 您的预期输出是什么?会发生什么然后你有第 1 行:08:30 - 11:00,第 2 行:09:00 - 10:30,第 3 行:09:30 - 10:00(即第 3 行嵌套在第 1 行和第 2 行中)。
  • @Noel 对。哎呀。你不会想知道我在这个问题上花了多少时间。
  • @MT0 这是我试图将所有这些组合在一起的更大查询的一部分。我想通过分析功能尝试这样做,只是一些自我教育出了问题:-)

标签: sql oracle oracle11g window-functions


【解决方案1】:

如果您使用ORDER BY start_dt asc range BETWEEN UNBOUNDED PRECEDING 1 PRECEDING Oracle 计算当前行的逻辑偏移量。 例子。 对于您示例中的第一行,范围是 08/07/2016 09:0007/07/2016 09:00 因为 (start_dt - 1) = 08/07/2016 09:00 -1 = 07/07/2016 09:00。 . 将范围更改为行

【讨论】:

  • 哦,哇,我现在是不是觉得自己很蠢。我从来没有想过使用ROWS 而不是RANGE。叹息 :-) 谢谢!
猜你喜欢
  • 1970-01-01
  • 2017-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-07
相关资源
最近更新 更多