0

我有如下数据

A        |  B      | C            |   D          |   E     |  F
217731   |  24856  | 01/01/2006   | 03/31/2007   |  0569   | 972450
217731   |  24856  | 04/01/2007   | 09/30/2008   |  0569   | 972450
217731   |  24856  | 10/01/2008   | 12/31/2008   |  0569   | 972450
217731   |  24856  | 01/01/2009   | 12/31/2009   |  0569   | 972450

217731   |  24856  | 01/01/2010   | 09/30/2011   |  0569   | 318704
217731   |  24856  | 10/01/2011   | 03/04/2012   |  0569   | 318704

217731   |  24856  | 03/05/2012   | 09/30/2012   |  0569   | 972450
217731   |  24856  | 10/01/2012   | 07/31/2013   |  0569   | 972450

我需要输出为

 A     |  B     |  C          | D           | F
217731 | 24856  |  01/01/2006 | 31/12/2009  | 972450
217731 | 24856  |  01/01/2010 | 04/03/2012  | 318704
217731 | 24856  |  05/03/2012 | 31/07/2013  | 972450

当我使用 group by 子句时,我得到如下输出

 A      |  B      | C          | D          | F
217731  | 24856   | 01/01/2006 | 07/31/2013 | 972450
217731  | 24856   | 01/01/2010 | 03/04/2012 | 318704
4

2 回答 2

1

您正在尝试识别具有相同密钥的不同时间段。幸运的是,Oracle 对此有丰富的分析功能,因为简单group by是不够的。

这是以下查询使用的逻辑。StartPeriod最里面的子查询根据行中的日期和键列创建一个标志 ( )。这标识了一个新时期的开始时间,因为 C 列不比前一个 D 列大 1 天。

然后,StartPeriod作为累积和累加。这将相同的值分配给同一时期的所有组。至此,有足够的信息可以使用group by。您需要包括附加grping列。

select A, B, MIN(C) as C, MAX(D) as D, E, F
from (select t.*, SUM(StartPeriod) over (partition by A, B, E, F order by C) as grping
      from (select t.*,
                   (case when lag(D) over (partition by A, B, E, F order by C) = C - 1
                         then 0
                         else 1
                    end) as StartPeriod
            from t
           ) t
     ) t
group by A, B, E, F, grping
于 2013-07-24T14:01:21.800 回答
0

如果您的表不大,也请尝试使用此查询:

select A,B,min(C),max(D),F
from
(
select t2.*,
(select count(A) from t where 
  (t.A<>t2.A or t.B<>t2.B or t.F<>t2.F) 
   and t.c<t2.c) Group_n
from t t2
 ) t3
group by A,B,F,Group_n

SQLFiddle 演示

于 2013-07-24T14:12:48.337 回答