提取多行连续期间涵盖的日期
Extract days covered in contiguous period over multiple rows
我在 Ingres 10 table 中有如下数据:-
ref, from_date, to_date
A, 01/04/2016, 30/04/2016
A, 30/04/2016, 20/05/2016
A, 25/05/2016, 30/05/2016
B, 01/04/2016, 01/09/2016
B, 01/10/2016, 20/02/2016
to_dates独享。
所以有些线组代表没有间隙的连续周期,它们可以跨越多条线,但有时会有间隙。
我需要计算每个连续期间所涵盖的天数。我想不出办法。
所以对于 ref A,我需要知道第一个连续时间段是 01/04/16 到 20/05/16 这个时间段有 46 天,第二个连续时间段是 25/05 /16 - 2016 年 5 月 30 日。这是 4 天。
我想不出在一个 SQL 语句中执行此操作的巧妙方法。接下来的答案依赖于创建 table 的副本并迭代更新它,直到每个周期都有一个 'earliest continuous from date'。那么这只是为每个ref和from date组合选择最大周期的问题。
在下面的示例中,我 运行 更新了两次,但是对于任意数据,您需要 运行 它直到更新更新 0 行。
另外,我冒昧地修正了日期中的几个拼写错误。
DECLARE GLOBAL TEMPORARY TABLE SESSION.test2 AS
SELECT ref AS ref,
from_date AS from_date,
to_date AS to_date,
from_date AS cont_from
FROM test
ON COMMIT PRESERVE ROWS
WITH NORECOVERY
Executing . . .
(5 rows)
continue
* * SELECT * FROM SESSION.test2
Executing . . .
+------+-------------------------+-------------------------+-------------------------+
|ref |from_date |to_date |cont_from |
+------+-------------------------+-------------------------+-------------------------+
|A |01-apr-2016 |30-apr-2016 |01-apr-2016 |
|A |30-apr-2016 |20-may-2016 |30-apr-2016 |
|A |25-may-2016 |30-may-2016 |25-may-2016 |
|B |01-apr-2016 |01-sep-2016 |01-apr-2016 |
|B |01-oct-2016 |20-feb-2017 |01-oct-2016 |
+------+-------------------------+-------------------------+-------------------------+
(5 rows)
continue
* * * * * * * * * * *
/* repeat this update until 0 rows are updated */
UPDATE SESSION.test2 b
FROM SESSION.test2 a
SET cont_from = a.cont_from
WHERE b.cont_from <= a.to_date
AND b.cont_from > a.from_date
AND b.ref = a.ref
AND b.cont_from != a.cont_from;
SELECT * FROM SESSION.test2
Executing . . .
(1 row)
+------+-------------------------+-------------------------+-------------------------+
|ref |from_date |to_date |cont_from |
+------+-------------------------+-------------------------+-------------------------+
|A |01-apr-2016 |30-apr-2016 |01-apr-2016 |
|A |30-apr-2016 |20-may-2016 |01-apr-2016 |
|A |25-may-2016 |30-may-2016 |25-may-2016 |
|B |01-apr-2016 |01-sep-2016 |01-apr-2016 |
|B |01-oct-2016 |20-feb-2017 |01-oct-2016 |
+------+-------------------------+-------------------------+-------------------------+
(5 rows)
continue
*
/* repeat this update until 0 rows are updated */
UPDATE SESSION.test2 b
FROM SESSION.test2 a
SET cont_from = a.cont_from
WHERE b.cont_from <= a.to_date
AND b.cont_from > a.from_date
AND b.ref = a.ref
AND b.cont_from != a.cont_from;
SELECT * FROM SESSION.test2
Executing . . .
(0 rows)
+------+-------------------------+-------------------------+-------------------------+
|ref |from_date |to_date |cont_from |
+------+-------------------------+-------------------------+-------------------------+
|A |01-apr-2016 |30-apr-2016 |01-apr-2016 |
|A |30-apr-2016 |20-may-2016 |01-apr-2016 |
|A |25-may-2016 |30-may-2016 |25-may-2016 |
|B |01-apr-2016 |01-sep-2016 |01-apr-2016 |
|B |01-oct-2016 |20-feb-2017 |01-oct-2016 |
+------+-------------------------+-------------------------+-------------------------+
(5 rows)
continue
* * * * * SELECT ref,cont_from,MAX(to_date - cont_from)
FROM SESSION.test2
GROUP BY ref,cont_from
ORDER BY 1,2
Executing . . .
+------+-------------------------+-------------------------+
|ref |cont_from |col3 |
+------+-------------------------+-------------------------+
|A |01-apr-2016 |49 days |
|A |25-may-2016 |5 days |
|B |01-apr-2016 |153 days |
|B |01-oct-2016 |142 days |
+------+-------------------------+-------------------------+
HTH
我在 Ingres 10 table 中有如下数据:-
ref, from_date, to_date
A, 01/04/2016, 30/04/2016
A, 30/04/2016, 20/05/2016
A, 25/05/2016, 30/05/2016
B, 01/04/2016, 01/09/2016
B, 01/10/2016, 20/02/2016
to_dates独享。
所以有些线组代表没有间隙的连续周期,它们可以跨越多条线,但有时会有间隙。
我需要计算每个连续期间所涵盖的天数。我想不出办法。
所以对于 ref A,我需要知道第一个连续时间段是 01/04/16 到 20/05/16 这个时间段有 46 天,第二个连续时间段是 25/05 /16 - 2016 年 5 月 30 日。这是 4 天。
我想不出在一个 SQL 语句中执行此操作的巧妙方法。接下来的答案依赖于创建 table 的副本并迭代更新它,直到每个周期都有一个 'earliest continuous from date'。那么这只是为每个ref和from date组合选择最大周期的问题。
在下面的示例中,我 运行 更新了两次,但是对于任意数据,您需要 运行 它直到更新更新 0 行。
另外,我冒昧地修正了日期中的几个拼写错误。
DECLARE GLOBAL TEMPORARY TABLE SESSION.test2 AS
SELECT ref AS ref,
from_date AS from_date,
to_date AS to_date,
from_date AS cont_from
FROM test
ON COMMIT PRESERVE ROWS
WITH NORECOVERY
Executing . . .
(5 rows)
continue
* * SELECT * FROM SESSION.test2
Executing . . .
+------+-------------------------+-------------------------+-------------------------+
|ref |from_date |to_date |cont_from |
+------+-------------------------+-------------------------+-------------------------+
|A |01-apr-2016 |30-apr-2016 |01-apr-2016 |
|A |30-apr-2016 |20-may-2016 |30-apr-2016 |
|A |25-may-2016 |30-may-2016 |25-may-2016 |
|B |01-apr-2016 |01-sep-2016 |01-apr-2016 |
|B |01-oct-2016 |20-feb-2017 |01-oct-2016 |
+------+-------------------------+-------------------------+-------------------------+
(5 rows)
continue
* * * * * * * * * * *
/* repeat this update until 0 rows are updated */
UPDATE SESSION.test2 b
FROM SESSION.test2 a
SET cont_from = a.cont_from
WHERE b.cont_from <= a.to_date
AND b.cont_from > a.from_date
AND b.ref = a.ref
AND b.cont_from != a.cont_from;
SELECT * FROM SESSION.test2
Executing . . .
(1 row)
+------+-------------------------+-------------------------+-------------------------+
|ref |from_date |to_date |cont_from |
+------+-------------------------+-------------------------+-------------------------+
|A |01-apr-2016 |30-apr-2016 |01-apr-2016 |
|A |30-apr-2016 |20-may-2016 |01-apr-2016 |
|A |25-may-2016 |30-may-2016 |25-may-2016 |
|B |01-apr-2016 |01-sep-2016 |01-apr-2016 |
|B |01-oct-2016 |20-feb-2017 |01-oct-2016 |
+------+-------------------------+-------------------------+-------------------------+
(5 rows)
continue
*
/* repeat this update until 0 rows are updated */
UPDATE SESSION.test2 b
FROM SESSION.test2 a
SET cont_from = a.cont_from
WHERE b.cont_from <= a.to_date
AND b.cont_from > a.from_date
AND b.ref = a.ref
AND b.cont_from != a.cont_from;
SELECT * FROM SESSION.test2
Executing . . .
(0 rows)
+------+-------------------------+-------------------------+-------------------------+
|ref |from_date |to_date |cont_from |
+------+-------------------------+-------------------------+-------------------------+
|A |01-apr-2016 |30-apr-2016 |01-apr-2016 |
|A |30-apr-2016 |20-may-2016 |01-apr-2016 |
|A |25-may-2016 |30-may-2016 |25-may-2016 |
|B |01-apr-2016 |01-sep-2016 |01-apr-2016 |
|B |01-oct-2016 |20-feb-2017 |01-oct-2016 |
+------+-------------------------+-------------------------+-------------------------+
(5 rows)
continue
* * * * * SELECT ref,cont_from,MAX(to_date - cont_from)
FROM SESSION.test2
GROUP BY ref,cont_from
ORDER BY 1,2
Executing . . .
+------+-------------------------+-------------------------+
|ref |cont_from |col3 |
+------+-------------------------+-------------------------+
|A |01-apr-2016 |49 days |
|A |25-may-2016 |5 days |
|B |01-apr-2016 |153 days |
|B |01-oct-2016 |142 days |
+------+-------------------------+-------------------------+
HTH