Sql 带开始和结束日期的组价格
我有一张桌子Sql 带开始和结束日期的组价格,sql,oracle,oracle11g,Sql,Oracle,Oracle11g,我有一张桌子 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-
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数据库以下是一种可能适用于您的情况的方法:
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
从您的示例数据中,我认为您希望在价格按照记录id的顺序进行更改时获得开始日期和结束日期。 由于可读性,以下查询可能包含的子查询多于必需的子查询。最内部的选择决定了什么时候价格发生了变化,这里称之为组变化。下一级通过滚动求和从组中删除。这是可能的,因为只有组更改包含大于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'));
我用下面的代码算出了
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
我不懂规则。如何确定价格20的两个输出记录?简单的第一,价格从第一个记录到第四个记录是20,作为前两个记录说,然后是一天30,作为int,第三个记录,然后是两天20,再次作为第四个记录基本上我需要一种方法将前两个记录与第四个记录分开,但我在计算上有困难原始表中的每条记录代表什么?这不是价格变化,因为记录1和记录2将由单个记录表示,该记录看起来像1 | 20 | 2017-10-01 | 2017-10-04,它有更多的数据列,并且每次拆分的任何列发生变化时,我看不出这应该解决它,您将1分配给第一个记录,0分配给第二个记录所以当你把它分组时,你得到了所有四个records@JacobGoldhirsch . . . 有一个你没有考虑的累积总数。好的,我明天会测试它。我测试了它,正如我昨天说的,它不会解决任何问题。使用{}图标在所见即所得编辑器或ctrl-K中放入代码块,我相信。谢谢!我很感激