进入开始行和匹配行,并继续到结束

时间:2019-06-24 17:50:15

标签: sql

我有以下观点:

+-------------+----------+--------+-----+
| PartitionBy | FirstDoc | EndDoc | Gap |
+-------------+----------+--------+-----+
| abc         |        1 |     10 |   0 |
| abc         |       11 |     30 |   0 |
| abc         |       31 |     34 |   2 |
| abc         |       37 |     40 |   0 |
| abc         |       41 |     50 |   3 |
| abc         |       54 |     60 |   0 |
| abc         |       61 |     70 |   0 |
| dce         |        2 |     10 |   0 |
| dce         |       11 |     15 |   2 |
| dce         |       18 |     20 |   0 |
| dce         |       21 |     30 |   2 |
| dce         |       33 |     40 |   0 |
+-------------+----------+--------+-----+

我正在尝试在找到Gap后将FirstDoc的起始位置移到EndDoc的末尾。这是我想要实现的目标:

+-------------+----------+--------+-----+
| PartitionBy | FirstDoc | EndDoc | Gap |
+-------------+----------+--------+-----+
| abc         |        1 |     34 |   2 |
| abc         |       37 |     50 |   3 |
| abc         |       54 |     70 |   0 |
| dce         |        2 |     15 |   2 |
| dce         |       18 |     30 |   2 |
| dce         |       33 |     40 |   0 |
+-------------+----------+--------+-----+

这就是我所做的

 SELECT PartitionBy, FirstDoc, EndDoc, GAP,
 CASE
    WHEN GAP =0 THEN MIN(FirstDoc)
    WHEN GAP >0 THEN MAX(EndDoc) 
    END as Datum
    from testgaptable group by PartitionBy, FirstDoc, EndDoc,Gap;

这给了我以下信息,在有间隙的情况下,数据确实取最后一个,但是,我无法弄清楚如何链接它以给出第一个和最后一个,并继续进行相同的分区。

+-------------+----------+--------+------+-------+
| PartitionBy | FirstDoc | EndDoc | GAP  | Datum |
+-------------+----------+--------+------+-------+
| abc         |     1.00 |  10.00 | 0.00 |  1.00 |
| abc         |    11.00 |  30.00 | 0.00 | 11.00 |
| abc         |    31.00 |  34.00 | 2.00 | 34.00 |
| abc         |    37.00 |  40.00 | 0.00 | 37.00 |
| abc         |    41.00 |  50.00 | 3.00 | 50.00 |
| abc         |    54.00 |  60.00 | 0.00 | 54.00 |
| abc         |    61.00 |  70.00 | 0.00 | 61.00 |
| dce         |     2.00 |  10.00 | 0.00 |  2.00 |
| dce         |    11.00 |  15.00 | 2.00 | 15.00 |
| dce         |    18.00 |  20.00 | 0.00 | 18.00 |
| dce         |    21.00 |  30.00 | 2.00 | 30.00 |
| dce         |    33.00 |  40.00 | 0.00 | 33.00 |
+-------------+----------+--------+------+-------+

1 个答案:

答案 0 :(得分:1)

如果您的RDBM支持sum作为window function,则可以创建一个人工列,以便按间隔之间的记录进行分组。

with cte as (
select *
    ,case when gap = 0 then 
                        sum(case when gap > 0 then 1 else 0 end) over (partition by PartitionBy order by FirstDoc asc)
          when gap > 0 then sum(case when gap > 0 then 1 else 0 end) over (partition by PartitionBy order by FirstDoc asc) - 1
     end as invisible_grouping
from v )
select 
     PartitionBy
    ,min(FirstDoc) as FirstDoc
    ,max(EndDoc) as EndDoc
    ,max(gap) as gap
from cte
group by PartitionBy, invisible_grouping
order by PartitionBy, FirstDoc

cte的输出:

PartitionBy FirstDoc    EndDoc  Gap invisible_grouping
abc              1        10    0           0
abc              11       30    0           0
abc              31       34    2           0
abc              37       40    0           1
abc              41       50    3           1
abc              54       60    0           2
abc              61       70    0           2
dce              2        10    0           0
dce              11       15    2           0
dce              18       20    0           1
dce              21       30    2           1
dce              33       40    0           2

我创建了另一列(invisible_grouping),对于要合并为一行的行,该列具有相同的值。然后,我在group by中使用了此列,但没有在select中使用。 最终输出:

PartitionBy FirstDoc    EndDoc  gap
abc             1          34   2
abc             37         50   3
abc             54         70   0
dce             2          15   2
dce             18         30   2
dce             33         40   0