合并SQL中的行(Oracle)

时间:2016-02-24 13:40:30

标签: sql oracle merge

我希望运行UPDATE,然后在必要时进行DELETE查询,在我的表上查询(让我们称之为MY_TABLE),这将以下列方式合并所有行。

输入表格

ID  LowerRange  UpperRange  Attribute
1   10          20          A
2   20          30          A
3   40          50          A
4   15          35          B

输出表格

ID  LowerRange  UpperRange  Attribute
1   10          30          A
3   40          50          A
4   15          35          B

请注意......

  1. 第1行和第1行输入表中的2将合并到输出表的第1行,因为它们的范围重叠并且它们具有相同的属性。
  2. 输入表的第3行未与第1行和第1行合并。 2因为它们的范围不重叠,尽管它们具有相同的属性。
  3. 输入表的第4行未与第1行和第1行合并。 2,因为它们没有相同的属性,尽管范围重叠。
  4. TABLE中的所有行都将合并到其范围重叠的位置,并且它们具有相同的属性。

    如果您有任何疑问,请与我们联系。任何帮助将不胜感激。

    谢谢, 斯蒂芬。

2 个答案:

答案 0 :(得分:1)

这是一种方式(假设您可能有重叠的行,其中当前行的起始范围小于或等于前一行的结束范围):

with sample_data as (select 1 id, 10 lower_range, 20 upper_range, 'A' attribute from dual union all
                     select 2 id, 20 lower_range, 30 upper_range, 'A' attribute from dual union all
                     select 3 id, 40 lower_range, 50 upper_range, 'A' attribute from dual union all
                     select 4 id, 15 lower_range, 35 upper_range, 'B' attribute from dual union all
                     select 5 id, 45 lower_range, 55 upper_range, 'A' attribute from dual union all
                     select 6 id, 16 lower_range, 34 upper_range, 'B' attribute from dual)
select min(id) id,
       min(lower_range) lower_range,
       max(upper_range) upper_range,
       attribute
from   (select id,
               lower_range,
               upper_range,
               attribute,
               sum(diff) over (partition by attribute order by lower_range, upper_range) grp
        from   (select id,
                       lower_range,
                       upper_range,
                       attribute,
                       case when lag(upper_range, 1, lower_range) over (partition by attribute order by lower_range, upper_range) >= lower_range then 0 else 1 end diff
                from   sample_data))
group by attribute, grp;

        ID LOWER_RANGE UPPER_RANGE ATTRIBUTE
---------- ----------- ----------- ---------
         1          10          30 A        
         3          40          55 A        
         4          15          35 B        

如果您的行仅在前一个upper_range与当前lower_range相同时才重叠,那么只需从case语句中删除>

这样做是看当前行的lower_range是否大于或等于前一行的upper_range。如果是,那么我们将结果设置为0,否则我们将其设置为1(这表示两行之间存在间隙)。

接下来,我们然后对每个属性的所有行执行累积和。对于重叠的行,这将具有相同的结果,并且每次遇到间隙时将增加1。

现在我们可以将它与属性列一起使用来对行进行分组,并找到它们的最小/最大范围以及min(id)。

答案 1 :(得分:0)