2016-06-26 18 views
0

xという名前のテーブルがあります。データは以下の通りです。私は現在、不連続なデータを識別するために、次のクエリを使用し連続した不連続な日付範囲を特定します

Acccount_num start_dt end_dt 
A111326  02/01/2016 02/11/2016 
A111326  02/12/2016 03/05/2016 
A111326  03/02/2016 03/16/2016 
A111331  02/28/2016 02/29/2016 
A111331  02/29/2016 03/29/2016 
A999999  08/25/2015 08/25/2015 
A999999  12/19/2015 12/22/2015 
A222222  11/06/2015 11/10/2015 
A222222  05/16/2016 05/17/2016 

両方A111326 A111331とは、連続したデータとして識別されなければならないとA999999と
A222222は、私のコードdata.In不連続として識別されなければなりません。また、A111326は不連続なデータとして誤って識別されます。 A111326が不連続なデータとして識別されないように、以下のコードを変更するのを手伝ってください。事前に助けていただきありがとうございます。あなたの問題の

(SELECT account_num 
       FROM (SELECT account_num, 
          (MAX (
           END_DT) 
           OVER (PARTITION BY account_num 
            ORDER BY START_DT)) 
           START_DT, 
          (LEAD (
           START_DT) 
           OVER (PARTITION BY account_num 
            ORDER BY START_DT)) 
           END_DT 
         FROM x 
         WHERE (START_DT + 1) <= 
           (END_DT - 1)) 
       WHERE START_DT < END_DT); 

答えて

0
WITH cte AS (
    SELECT 
     AccountNumber 
     ,CASE 
      WHEN 
      LAG(End_Dt) OVER (PARTITION BY AccountNumber ORDER BY End_Dt) IS NULL THEN 0 
      WHEN 
      LAG(End_Dt) OVER (PARTITION BY AccountNumber ORDER BY End_Dt) >= Start_Dt - 1 THEN 0 
      ELSE 1 
     END as discontiguous 
    FROM 
     #Table 
) 

SELECT 
    AccountNumber 
    ,CASE WHEN SUM(discontiguous) > 0 THEN 'discontiguous' ELSE 'contiguous' END 
FROM 
    cte 
GROUP BY 
    AccountNumber; 

Oneを連続した所望の結果はまた、あなたの例のデータセット内の重複日付範囲が含まれていることです。例A1113263/2/2016で始まり、前に行を終了して3/5/2015と重複していることを意味します。

+0

おかげで解決のためにたくさん。それは本当に働いた。私は連続して重複するデータを持っていますが、これはうまくいきます。 – manj

+0

はい私はそれが連続として数えられるようにするために重複に気付いたときにクエリを変更しました。将来的に重なり合った変更> = Start_Dt - 1〜= Start_Dt - 1を含めたくない場合は、それを受け入れることができたらうれしいです。http://meta.stackexchange.com/questions/5234/how-does-accept-an-answer-work) – Matt

+0

行「E」、日付「2016-01-01」、日付「2016-01-02」を試してください。 '' E '、DATE' 2016-01-05 '、DATE' 2016-01-06''; 'E '、DATE' 2016-01-03 '、DATE' 2016-01-07 'のように、実際に'連続しているときは 'discontiguous'を出力します。 – MT0

2

Oracleのセットアップ

CREATE TABLE accounts (Account_num, start_dt, end_dt) AS 
SELECT 'A', DATE '2016-02-01', DATE '2016-02-11' FROM DUAL UNION ALL 
SELECT 'A', DATE '2016-02-12', DATE '2016-03-05' FROM DUAL UNION ALL 
SELECT 'A', DATE '2016-03-02', DATE '2016-03-16' FROM DUAL UNION ALL 
SELECT 'B', DATE '2016-02-28', DATE '2016-02-29' FROM DUAL UNION ALL 
SELECT 'B', DATE '2016-02-29', DATE '2016-03-29' FROM DUAL UNION ALL 
SELECT 'C', DATE '2015-08-25', DATE '2015-08-25' FROM DUAL UNION ALL 
SELECT 'C', DATE '2015-12-19', DATE '2015-12-22' FROM DUAL UNION ALL 
SELECT 'D', DATE '2015-11-06', DATE '2015-11-10' FROM DUAL UNION ALL 
SELECT 'D', DATE '2016-05-16', DATE '2016-05-17' FROM DUAL UNION ALL 
SELECT 'E', DATE '2016-01-01', DATE '2016-01-02' FROM DUAL UNION ALL 
SELECT 'E', DATE '2016-01-05', DATE '2016-01-06' FROM DUAL UNION ALL 
SELECT 'E', DATE '2016-01-03', DATE '2016-01-07' FROM DUAL; 

クエリ

WITH times (account_num, dt, lvl) AS (
    SELECT Account_num, start_dt - 1, 1 FROM accounts 
UNION ALL 
    SELECT Account_num, end_dt,  -1 FROM accounts 
) 
, totals (account_num, dt, total) AS (
    SELECT account_num, 
     dt, 
     SUM(lvl) OVER (PARTITION BY Account_num ORDER BY dt, lvl DESC) 
    FROM times 
) 
SELECT Account_num, 
     CASE WHEN COUNT(CASE total WHEN 0 THEN 1 END) > 1 
      THEN 'N' 
      ELSE 'Y' 
      END AS is_contiguous 
FROM totals 
GROUP BY Account_Num 
ORDER BY Account_Num; 

出力

ACCOUNT_NUM IS_CONTIGUOUS 
----------- ------------- 
A   Y 
B   Y 
C   N 
D   N 
E   Y 

もうひとつのクエリ

(それはちょうどUNION ALLではなくUNPIVOTを使用して、まったく同じ方法です。)

SELECT Account_num, 
     CASE WHEN COUNT(CASE total WHEN 0 THEN 1 END) > 1 
      THEN 'N' 
      ELSE 'Y' 
      END AS is_contiguous 
FROM (
    SELECT Account_num, 
     SUM(lvl) OVER (PARTITION BY Account_Num 
          ORDER BY CASE lvl WHEN 1 THEN dt - 1 ELSE dt END, 
            lvl DESC 
         ) AS total 
    FROM accounts 
    UNPIVOT (dt FOR lvl IN (start_dt AS 1, end_dt AS -1)) 
) 
GROUP BY Account_Num 
ORDER BY Account_Num; 
+0

私はこのパターンが好きです。日付とレベルの積算合計です。私はこれがより完全な証拠であり、第3行が連続していて、第2行が連続していないときの問題を処理することに同意します。答えをありがとうと私はおそらくこれをもう一度使用することに注意してください。 – Matt

+0

@Matt - それは上記の方法の最初の2つの部分を使用して重複する範囲の開始日と終了日を抽出する[この質問](http://stackoverflow.com/a/35521818/1509264) 'LAG(...)IGNORE NULLS')。 – MT0

関連する問題