2017-02-16 148 views
-1

嗨值我有以下日常数据:分组基础上按日期范围

daytime  value 
01.01.2017  20000 
02.01.2017  20000 
03.01.2017  20000 
04.01.2017  35000 
05.01.2017  35000 
06.01.2017  40000 
07.01.2017  40000 
08.01.2017  50000 

我怎么能有日期范围格式,如下面?

FromDate  ToDate  Value 
01.01.2017 03.01.2017 20000 
04.01.2017 05.01.2017 35000 
06.01.2017 07.01.2017 40000 
08.01.2017 08.01.2017 50000 

谢谢!

回答

3

Tabibitosan处理这个问题很容易:

WITH your_table AS (SELECT to_date('01/01/2017', 'dd/mm/yyyy') daytime, 20000 VALUE FROM dual UNION ALL 
        SELECT to_date('02/01/2017', 'dd/mm/yyyy') daytime, 20000 VALUE FROM dual UNION ALL 
        SELECT to_date('03/01/2017', 'dd/mm/yyyy') daytime, 20000 VALUE FROM dual UNION ALL 
        SELECT to_date('04/01/2017', 'dd/mm/yyyy') daytime, 35000 VALUE FROM dual UNION ALL 
        SELECT to_date('05/01/2017', 'dd/mm/yyyy') daytime, 35000 VALUE FROM dual UNION ALL 
        SELECT to_date('06/01/2017', 'dd/mm/yyyy') daytime, 40000 VALUE FROM dual UNION ALL 
        SELECT to_date('07/01/2017', 'dd/mm/yyyy') daytime, 40000 VALUE FROM dual UNION ALL 
        SELECT to_date('08/01/2017', 'dd/mm/yyyy') daytime, 50000 VALUE FROM dual UNION ALL 
        SELECT to_date('09/01/2017', 'dd/mm/yyyy') daytime, 20000 VALUE FROM dual) 
-- end of mimicking your table with data in it. See SQL below: 
SELECT MIN(daytime) fromdate, 
     MAX(daytime) todate, 
     VALUE 
FROM (SELECT daytime, 
       VALUE, 
       row_number() OVER (ORDER BY daytime) - row_number() OVER (PARTITION BY VALUE ORDER BY daytime) grp 
     FROM your_table) 
GROUP BY grp, 
     VALUE 
ORDER BY MIN(daytime); 

FROMDATE TODATE   VALUE 
---------- ---------- ---------- 
01/01/2017 03/01/2017  20000 
04/01/2017 05/01/2017  35000 
06/01/2017 07/01/2017  40000 
08/01/2017 08/01/2017  50000 
09/01/2017 09/01/2017  20000 

这样做有什么比较的行数按日期排序的所有行,然后将行号对于按日期排序的每个值的所有行。如果主数据集中的值行是连续的,那么两组数据之间的差异保持不变,因此您可以按此组合。如果存在差距,则差异增加。

在上面的例子中,value = 20000的前三行碰巧是整个集合的前三行,所以差异将是0.但是第四个值= 20000行是整个第九行因此差异现在为5.您可以很容易地看到,20000的值分为两组,因此可以通过在group by子句中包括差异计算来分别找到每个组的最小/最大白天时间。

N.B.这确实假设您的数据中的日期是连续的,或者如果缺少日期,则假定该值在缺失日期保持不变。如果您确实缺少时间,并希望跨不同组显示差距,则需要将外连接加入包含缺失日期的子查询中。在这种情况下,我认为GurV的答案(在评论中提到的案例声明中的附加条款)将是最好的一个,因为这样可以避免将外部连接加入到连续日期列表中。

+0

宾果!有用!非常感谢你:) – akira

+0

不确定你的意思是N.B. - 也许你的意思是,如果顶部有十行,所有值都是20000,但日期是连续四天,那么一个差距,然后连续六天,这应该产生两行而不是一行...如果这就是你的意思,然后** Tabibitosan **的小修改可以直接处理。要创建'grp',使用'daytime'本身而不是第一个'row_number()';这样'grp'值最终会成为日期而不是数字,但整个事情的工作方式完全相同。 – mathguy

+0

好点,ta;我从来没有想过要这样做!星期一将有一个玩弄* {:-) – Boneist

1

如果我理解正确,只要它们对连续日期相同即可。

您可以使用窗口函数根据值生成组,并增加日期顺序,然后查找所需的聚合。

with your_table(daytime  ,value) as (
    select to_date('13.02.2017','dd.mm.yyyy'),25000 from dual union all 
    select to_date('14.02.2017','dd.mm.yyyy'),20000 from dual union all 
    select to_date('15.01.2017','dd.mm.yyyy'),90000 from dual union all 
    select to_date('16.01.2017','dd.mm.yyyy'),90000 from dual union all 
    select to_date('17.01.2017','dd.mm.yyyy'),95800 from dual union all 
    select to_date('18.01.2017','dd.mm.yyyy'),95800 from dual union all 
    select to_date('19.01.2017','dd.mm.yyyy'),95800 from dual union all 
    select to_date('20.01.2017','dd.mm.yyyy'),95800 from dual union all 
    select to_date('21.01.2017','dd.mm.yyyy'),95800 from dual union all 
    select to_date('22.01.2017','dd.mm.yyyy'),95800 from dual union all 
    select to_date('23.01.2017','dd.mm.yyyy'),95800 from dual union all 
    select to_date('24.01.2017','dd.mm.yyyy'),90000 from dual union all 
    select to_date('25.01.2017','dd.mm.yyyy'),90000 from dual union all 
    select to_date('26.01.2017','dd.mm.yyyy'),90000 from dual 
) 
select 
    min(daytime) fromdate, 
    max(daytime) todate, 
    value 
from (
    select 
     t.*, 
     sum(x) over (order by daytime) grp 
    from (
     select 
      t.*, 
      case when value = lag(value) over (order by daytime) 
      then 0 else 1 end x 
     from your_table t 
    ) t 
) t group by grp, value 
order by fromdate; 

产地:

FROMDATE TODATE  VALUE 
15-JAN-17 16-JAN-17 90000 
17-JAN-17 23-JAN-17 95800 
24-JAN-17 26-JAN-17 90000 
13-FEB-17 13-FEB-17 25000 
14-FEB-17 14-FEB-17 20000 
+0

嗨,我看到与您的解决方案重复的价值,我会稍后展示示例,谢谢! – akira

+0

@akirax你是什么意思你看到与GurV的解决方案重复值?看起来它适用于我,当我用一些测试数据尝试它时。它肯定会给出你输入数据的输出结果。 – Boneist

+0

@akirax - 它确实有效。请参阅更新 – GurV