2016-11-18 7 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が排他的にしています。

このように、行の一部はギャップのない連続したピリオドを表しますが、これらは複数の行にまたがる場合がありますが、ギャップがあることもあります。

私は、各連続期間にカバーされる日数を数える必要があります。私はこれを行う方法を考えることができません。

したがって、最初の連続期間が01/04/16から20/05/16で、この期間に46日あり、2番目の連続期間が25/05/16 - 30/05/16。これは4日間です。

+0

その後、よりすべてのconinuous日は、このテーブルに参加残したテーブルを作ります。ヌルの行は連続していません – Hogan

+0

私はどのようにして「すべての連続した日を持つテーブルを作るのか」を理解できません。 –

+0

他のテーブルを作るのと同じ方法で、ステートメントを挿入するか、スクリプトを作成することができます。 – Hogan

答えて

1

私は、1つのSQL文でこれを行う巧妙な方法を考えることはできません。以下の答えは、テーブルのコピーを作成し、各期間の「最も古い日付から最も早い日付」まで繰り返し更新します。それでは、それぞれの参照と日付の組み合わせで最大の期間を選択するだけの問題です。

以下の例では、更新プログラムを2回実行していますが、任意のデータを使用すると、更新プログラムによって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/ここで死に至ったので、おそらくその記事はSQL Serverに基づいていることを指摘しておきたいと思うでしょう。 – Hogan

+1

Ingresは、一部のソリューションに含まれるすべてのSQL構文をサポートしていません。私はソリューション#1はまだ動作すると思います。 – PaulM

関連する問題