给定这样的表(dt
列是唯一的):
id | dt | days_count
------------------------------
1 | 2015-06-01 | NULL
2 | 2015-06-03 | NULL
4 | 2015-06-09 | NULL
我需要计算最近日期之间的间隔天数,并在days_count
列中更新检索结果,并且计算必须以最新日期开始。也就是说,需要的结果是:
id | dt | days_count
------------------------------
1 | 2015-06-01 | NULL
2 | 2015-06-03 | 2
4 | 2015-06-09 | 6
我有2个变种:
使用PL/SQL FOR (SELECT ..) LOOP
,获取按dt desc
排序的每一行,并计算当前行日期与上一行日期之间的间隔天数。
变体2
MERGE INTO mytable
USING(
WITH
t1 as (SELECT id, dt, row_number() over(order by dt) as rn from mytable),
t2 as (SELECT id, dt, row_number() over(order by dt) + 1 as rn from mytable)
SELECT t1.id, t1.rn, t1.dt - t2.dt as days_count from t1
left JOIN t2
on
t1.rn = t2.rn
) day_interval
ON (mytable.id = day_interval.id)
WHEN MATCHED THEN UPDATE SET
mytable.days_count= day_interval.days_count
这些变体有效,但问题是:为此可能有更有效的方法吗?
答案 0 :(得分:3)
永远不要在 PL / SQL 中执行此操作,只能在纯 SQL 中执行此操作。
您可以使用 LAG()OVER()分析函数来执行此操作。
例如,
<强>设置强>
SQL> CREATE TABLE t
2 (id int, dt date, days_count varchar2(4));
Table created.
SQL>
SQL> INSERT ALL
2 INTO t (id, dt, days_count)
3 VALUES (1, to_date('2015-06-01','YYYY-MM-DD'), NULL)
4 INTO t (id, dt, days_count)
5 VALUES (2, to_date('2015-06-03','YYYY-MM-DD'), NULL)
6 INTO t (ID, dt, days_count)
7 VALUES (4, to_date('2015-06-09','YYYY-MM-DD'), NULL)
8 SELECT * FROM dual;
3 rows created.
SQL>
<强>查询强>
SQL> SELECT id, dt, dt - lag(dt) over(order by dt) days_count FROM t;
ID DT DAYS_COUNT
---------- --------- ----------
1 01-JUN-15
2 03-JUN-15 2
4 09-JUN-15 6
SQL>
MERGE声明
SQL> MERGE INTO t
2 USING(
3 SELECT id, dt, dt - lag(dt) over(order by dt) days_count FROM t
4 ) day_interval
5 ON (t.id = day_interval.id)
6 WHEN MATCHED THEN UPDATE SET
7 t.days_count= day_interval.days_count;
3 rows merged.
SQL> SELECT * FROM t;
ID DT DAYS
---------- --------- ----
1 01-JUN-15
2 03-JUN-15 2
4 09-JUN-15 6
SQL>