2016-11-18 5 views
0

나는 다음과 같은 앵그르 (10) 테이블의 데이터를 가지고있다 -추출 일

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 - 30/05/16. 그리고 이것은 4 일입니다.

+0

다음보다 모든 coninuous 일이 테이블에 가입 남아있는 테이블을합니다. null이있는 행은 연속적이 아닙니다. – Hogan

+0

'어떻게 모든 연속적인 일을 가진 테이블을 만들 수 있을지 이해하지 못합니까? –

+0

다른 테이블을 만드는 것과 같은 방법으로 문장을 삽입하거나 스크립트를 작성할 수 있습니다. – Hogan

답변

1

하나의 SQL 문에서이를 수행하는 영리한 방법을 생각할 수 없습니다. 다음의 대답은 테이블 복사본을 만들고 각 기간에 대해 '가장 이른 날짜부터'까지 반복적으로 업데이트합니다. 그렇다면 각 심판과 날짜 조합에서 가장 큰 기간을 선택하는 것입니다.

아래 예에서는 업데이트를 두 번 실행했지만 임의 데이터의 경우 업데이트가 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

+0

간단하고 잘 이해되는 연속 일을 찾는 방법이 있습니다. 다음은 문제를 탐구하는 멋진 기사입니다 : https://www.simple-talk.com/sql/t-sql-programming/the-sql-of-gaps-and-islands-in-sequences/ 여기에 죽음에 맞춰서 그리고 이것은 아마도 중복으로 표시되어야합니다 – Hogan

+1

가치가 그 기사는 SQL Server를 기반으로 지적했다. Ingres는 일부 솔루션에 나타나는 모든 SQL 구문을 지원하지 않습니다. 나는 해결책 # 1이 아직도 일할 것이라고 생각한다. – PaulM