即使重复值不同,也将数据分组到不同的分区中

时间:2019-03-06 06:00:23

标签: sql oracle

我有类似的数据:

Arrange Id  |  Begin Date | End Date | Dept Id
------------+-------------+----------+-----------
 11345         01/02/2001   02/03/2003   2230
 11345         02/03/2004   04/05/2005   2230
 11345         04/06/2005   06/06/2006   2210
 11345         05/06/2007   07/09/2008   2210
 11345         08/09/2009   11/23/2010   2230
 11454         04/01/2008   04/07/2008   1100
 11454         04/08/2008   05/06/2009   1100
 11454         05/07/2009   07/09/2010   1300
 11454         08/07/2011   10/23/2012   1100

预期输出:

 Arrange Id | Begin Date | End Date    | Dept Id
------------+-------------+----------+-----------
 11345        01/02/2001   04/05/2005   2230
 11345        04/06/2005   07/09/2008   2210
 11345        08/09/2009   11/23/2010   2230
 11454        04/01/2008   05/06/2009   1100
 11454        05/07/2009   07/09/2010   1300
 11454        08/07/2011   10/23/2012   1100

我希望基于Arrange Id对数据进行分区,我需要为每个Min(Begin Date)Max(End Date)分别记录Arrange idDept Id个日期。 {1}}是重复的,例如最初是6620、6630、6640,然后是6620等。

我需要按照上面显示的预期输出显示值。如果在上述情况下,例如,在上述情况下,我基于Dept Id分区,例如11345,2230 dept id,我得到的是单个值,但是我需要两个不同的值如上图所示。

有人可以通过编写SQL查询(针对Oracle)为我提供有关此解决方案的帮助吗?

2 个答案:

答案 0 :(得分:0)

好的,因此您必须保持自己的顺序才能执行所需的操作。因此,我使用行号和等级来查找您要查找的特定岛屿。这基于您的组被其他ArrangeID隔开的假设:

SELECT arrangeid, 
       MIN(begindate) AS BEGINDATE, 
       MAX(enddate)   AS ENDDATE, 
       deptid 
FROM  
    (
        SELECT arrangeid, 
               begindate, 
               enddate, 
               deptid, 
               DENSE_RANK() OVER (PARTITION BY arrangeid, deptid ORDER BY rn) AS grp 
        FROM   (
                SELECT arrangeid, 
                       begindate, 
                       enddate, 
                       deptid, 
                       ROW_NUMBER() OVER ( PARTITION BY arrangeid ORDER BY begindate) -
                       RANK() OVER ( PARTITION BY arrangeid, deptid ORDER BY begindate) AS rn 
                FROM   arrange
                ) rawdata
    ) ranked 
GROUP  BY arrangeid, 
          deptid, 
          grp 
ORDER  BY arrangeid, 
          deptid 

哪个给出输出:

ARRANGEID   BEGINDATE               ENDDATE                 DEPTID
11345       2005-04-06T00:00:00Z    2008-07-09T00:00:00Z    2210    
11345       2009-08-09T00:00:00Z    2010-11-23T00:00:00Z    2230
11345       2001-01-02T00:00:00Z    2005-04-05T00:00:00Z    2230
11454       2008-04-01T00:00:00Z    2009-05-06T00:00:00Z    1100
11454       2009-05-07T00:00:00Z    2010-07-09T00:00:00Z    1300
11454       2011-08-07T00:00:00Z    2012-10-23T00:00:00Z    1100

您可以在这里找到小提琴:http://sqlfiddle.com/#!4/17b162/49

答案 1 :(得分:0)

这是一个空白问题,您必须将起点和终点结合起来。

这个想法是找到开始一个岛的行。您可以通过查找与现有行不重叠的“开始”来做到这一点。然后,累计这些计数并进行汇总:

select arrange_id, dept_id, min(begin_date), max(end_date)
from (select t.*,
             sum(case when prev_end_date >= begin_date then 0
                      else 1
                 end) over (partition by arrange_id, dept_id) as grp
      from (select t.*,
                   max(end_date) over (partition by arrange_id, dept_id
                                       order by begin_date, end_date
                                       rows between unbounded preceding and 1 preceding
                                      ) as prev_end_date
            from t
           ) t
      ) t
group by arrange_id, dept_id, grp;