0

以下のデータから適切な順序の出力を取得するのに役立つ SQL クエリを作成しようとしています。

表のデータ:

Cust   num     Eff_Date     Exp_date           
1001   1234    10-01-2010   20-06-2010      
1001   1234    20-06-2010   25-06-2010       
1001   1234    25-06-2010   12-02-2011          
1001   1234    12-02-2011   12-02-2011            
1001   3456    12-02-2011   25-07-2012      
1001   3456    25-07-2012   25-07-2012      
1001   1234    25-07-2012   25-07-2012      
1001   1234    25-07-2012   31-12-4700   

Query の期待される出力:

Cust   num     Eff_Date     Exp_date           
1001   1234    10-01-2010   12-02-2011      
1001   3456    12-02-2011   25-07-2012      
1001   1234    25-07-2012   31-12-4700   

単一の SQL ステートメントを使用して上記を実行できるようにしたいと考えています。単一の SQL ステートメントを使用して上記を行うことは可能ですか? 上記を行う別の方法はありますか。

4

3 に答える 3

1
SELECT
  Customer,
  `number` AS Number,
  MIN(Eff_Date) AS Eff_Date,
  MAX(Exp_date) AS Exp_date
FROM tablename
GROUP BY Customer, number
于 2012-12-25T13:52:20.933 に答える
0

これはpostgresで機能しますが、マイナーな変更を加えてOracleに適応させることができます. 注: 間隔の重複は妥当とは思えないため、データを少し変更しました。

DROP SCHEMA tmp CASCADE;
CREATE SCHEMA tmp ;
SET search_path=tmp;

CREATE TABLE lutser
        ( cust INTEGER NOT NULL
        , num iNTEGER NOT NULL
        , eff_date DATE NOT NULL
        , exp_date DATE NOT NULL
        , PRIMARY KEY (cust, num, eff_date)
        );

SET datestyle=german;

INSERT INTO lutser(cust,num,eff_date,exp_date) VALUES
 (1001,1234,'10-01-2010', '20-06-2010' )
,(1001,1234,'20-06-2010', '25-06-2010' )
,(1001,1234,'25-06-2010', '12-02-2011' )
,(1001,1234,'12-02-2011', '12-02-2011' )
,(1001,3456,'12-02-2011', '25-07-2012' )
,(1001,3456,'25-07-2012', '25-07-2012' )
,(1001,1234,'25-07-2012', '25-08-2012' ) -- added a month to get unique PK
,(1001,1234,'25-08-2012', '31-12-4700' ) -- and here as well
        ;

VACUUM ANALYZE lutser;

-- SELECT * FROM lutser ORDER BY cust,num,eff_date;

-- EXPLAIN ANALYZE
WITH RECURSIVE island AS
        ( SELECT cust,num,eff_date,exp_date
        FROM lutser l0
        WHERE NOT EXISTS
                ( SELECT *
                FROM lutser nx
                WHERE nx.cust = l0.cust AND nx.num = l0.num
                AND nx.eff_date < l0.eff_date
                AND nx.exp_date >= l0.eff_date
                )
        UNION -- ALL
        SELECT isl.cust,isl.num, isl.eff_date,l1.exp_date
        FROM lutser l1
        JOIN island isl ON isl.cust = l1.cust AND isl.num = l1.num
                AND isl.eff_date < l1.eff_date
                AND isl.exp_date >= l1.eff_date
        )
SELECT DISTINCT ON (cust,num,eff_date) *
FROM island
ORDER BY cust,num,eff_date
        ;

結果:

NOTICE:  drop cascades to table tmp.lutser
DROP SCHEMA
CREATE SCHEMA
SET
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "lutser_pkey" for table "lutser"
CREATE TABLE
SET
INSERT 0 8
VACUUM
 cust | num  |  eff_date  |  exp_date  
------+------+------------+------------
 1001 | 1234 | 10.01.2010 | 20.06.2010
 1001 | 1234 | 25.07.2012 | 25.08.2012
 1001 | 3456 | 12.02.2011 | 25.07.2012
(3 rows)
于 2012-12-25T15:05:06.163 に答える
0

Oracle では、分析関数を使用して島をグループ化できます。

SQL> select c.cust, c.num, min(eff_date) eff_date, max(exp_Date) exp_date
  2    from (select c.cust, c.num, c.eff_date, c.exp_date, max(rn) over (partition by cust, num order by eff_date) grp
  3            from (select c.cust, c.num, c.eff_date, c.exp_date,
  4                         case
  5                           when lag(exp_date, 1) over (partition by cust, num order by eff_date) != eff_date
  6                           then
  7                             row_number() over (partition by cust, num order by eff_date)
  8                           when row_number() over (partition by cust, num order by eff_date) = 1
  9                           then
 10                             1
 11                        end rn
 12                    from cust c) c) c
 13    group by c.cust, c.num, grp
 14    order by eff_date;

      CUST        NUM EFF_DATE   EXP_DATE
---------- ---------- ---------- ----------
      1001       1234 10-01-2010 12-02-2011
      1001       3456 12-02-2011 25-07-2012
      1001       1234 25-07-2012 31-12-4700

SQL>
于 2012-12-30T16:18:08.873 に答える