我有类似的数据:
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 id
和Dept Id
个日期。 {1}}是重复的,例如最初是6620、6630、6640,然后是6620等。
我需要按照上面显示的预期输出显示值。如果在上述情况下,例如,在上述情况下,我基于Dept Id
分区,例如11345,2230 dept id,我得到的是单个值,但是我需要两个不同的值如上图所示。
有人可以通过编写SQL查询(针对Oracle)为我提供有关此解决方案的帮助吗?
答案 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;