2017-10-18 30 views
1

我有一个表集团的价格与开始和结束日期

Recordid Price Start date end date 
----------------------------------------- 
1  20  2017-10-01 2017-10-02 
2  20  2017-10-03 2017-10-04 
3  30  2017-10-05 2017-10-05 
4  20  2017-10-06 2017-10-07 

我想每一个价格,当它开始和结束的,所以我的结果集将

20. 2017-10-01. 2017-10-04 
30. 2017-10-05. 2017-10-05 
20. 2017-10-06. 2017-10-07 

我有问题要弄清楚

这是一个Oracle数据库

+0

我不明白规则。你如何确定价格20的两个输出记录? – OldProgrammer

+0

简单的第一个价格是从第一个到第四个20作为前两个记录说那么它是一天30作为整数第三个记录然后两天20再次如第四个记录 –

+0

基本上我需要一种方法来组合第一个两条记录与第四条分开,但我无法计算出 –

回答

1

我用下面的代码想通了测试

SELECT distinct price 
     , case when start_dt is null then lag(start_dt) over (order by start_date) 
      else start_dt end realstart 
     , case when end_dt is null then lead(end_dt) over (order by end_date) 
      else end_dt end realend 
FROM (SELECT case when nvl(lag(price) over (order by start_date),-1) <> price then start_date end start_dt 
      , case when nvl(lead(price) over (order by end_date),-1) <>price then end_date end end_dt 
      , price 
      , start_date 
      , end_date 
     FROM t) main 
WHERE start_dt is not null 
    or end_dt is not null 
+0

使用{}图标将所见即所得编辑器中的代码块或ctrl-K放入代码块。 – xQbert

+0

谢谢!我很感激 –

0

这里有一个方法,可以在你的工作案例:

select price, min(start_date), max(end_date) 
from (select t.*, 
      sum(case when prev_price = price and prev_end_date = start_date - 1 
         then 0 else 1 
       end) over (order by t.start_date) as grp 
     from (select t.*, 
        lag(t.end_date) over (order by t.start_date) as prev_end_date, 
        lag(t.price) over (order by t.start_date) as prev_price 
      from t 
      ) t 
    ) t 
group by price, grp 
+0

我没有看到这应该可以解决它 您指定1到第一个记录0到第二个当你将它分组时,你会得到所有四条记录 –

+0

@JacobGoldhirsch。 。 。有一个累计总和,你没有考虑到。 –

+0

好的,我明天会测试 –

0

从你的样本数据,我认为你想拥有的开始日期,并且只要价格在备案编号的顺序被改变的结束日期。 以下查询可能包含比必要更多的子查询,因为可读性。非常内在的选择决定了价格何时发生变化,称为集团变化。下一个级别是来自该组的滚动总和。这是可能的,因为只有组更改包含> 0的值。其余显而易见。

SELECT GRP, 
     PRICE, 
     MIN("Start date") AS "Start date", 
     MAX("end date") AS "end date" 
    FROM (SELECT sub.*, 
       SUM(GROUP_CHANGE) OVER (ORDER BY RECORDID) AS GRP 
      FROM (SELECT t.*, 
         CASE 
          WHEN RECORDID = LAG(t.RECORDID) OVER (ORDER BY t.PRICE, t.RECORDID) + 1 
           THEN 0 
          ELSE RECORDID 
         END AS GROUP_CHANGE 
        FROM t) sub) fin 
GROUP BY GRP, PRICE 
ORDER BY GRP 


     GRP  PRICE Start date end date 
---------- ---------- ---------- -------- 
     1   20 01.10.17 04.10.17 
     4   30 05.10.17 05.10.17 
     8   20 06.10.17 11.10.17 

与下面的数据(请注意,我有添加一些记录到您的deliverd样本数据,我想有三个记录一组)

CREATE TABLE t (
    Recordid  INT, 
    Price  INT, 
    "Start date" DATE, 
    "end date" DATE 
); 

INSERT INTO t VALUES (1,  20,  TO_DATE('2017-10-01', 'YYYY-MM-DD'), TO_DATE('2017-10-02', 'YYYY-MM-DD')); 
INSERT INTO t VALUES (2,  20,  TO_DATE('2017-10-03', 'YYYY-MM-DD'), TO_DATE('2017-10-04', 'YYYY-MM-DD')); 
INSERT INTO t VALUES (3,  30,  TO_DATE('2017-10-05', 'YYYY-MM-DD'), TO_DATE('2017-10-05', 'YYYY-MM-DD')); 
INSERT INTO t VALUES (4,  20,  TO_DATE('2017-10-06', 'YYYY-MM-DD'), TO_DATE('2017-10-07', 'YYYY-MM-DD')); 
INSERT INTO t VALUES (5,  20,  TO_DATE('2017-10-08', 'YYYY-MM-DD'), TO_DATE('2017-10-09', 'YYYY-MM-DD')); 
INSERT INTO t VALUES (6,  20,  TO_DATE('2017-10-10', 'YYYY-MM-DD'), TO_DATE('2017-10-11', 'YYYY-MM-DD')); 
相关问题