如何将 Oracle 查询写入如下所示的组?
How to write Oracle query to group like below?
Id value
1 5
1 6
1 8
1 9
1 10
结果应该如下所示
Id minValue maxValue
1 5 6
1 8 10
前一个值差应该是1否则需要插入其他行
这就是著名的 GAPS 和 ISLANDS 问题。您可以阅读 this wonderful article from Lalit Kumar B 了解详细说明。您可以尝试以下查询 -
SELECT id, MIN(value), MAX(value)
FROM (SELECT id, value, value - ROW_NUMBER() OVER(PARTITION BY id ORDER BY value) rn
FROM test) T
GROUP BY id, rn;
这是Fiddle
如果您从值本身中减去每个值在该 ID 的值列表中的位置(您可以使用分析函数获得):
value - dense_rank() over (partition by id order by value)
那么连续(或重复)的值将得到相同的结果:
select id, value,
value - dense_rank() over (partition by id order by value)
from your_table;
ID VALUE GRP
---------- ---------- ----------
1 5 4
1 6 4
1 8 5
1 9 5
1 10 5
然后您可以使用这些差异进行汇总:
select id, min(value) as minvalue, max(value) as maxvalue
from (
select id, value,
value - dense_rank() over (partition by id order by value) as grp
from your_table
)
group by id, grp
order by id, minvalue;
ID MINVALUE MAXVALUE
---------- ---------- ----------
1 5 6
1 8 10
如果没有重复,您可以使用 row_number()
instead of dense_rank()
。
Id value
1 5
1 6
1 8
1 9
1 10
结果应该如下所示
Id minValue maxValue
1 5 6
1 8 10
前一个值差应该是1否则需要插入其他行
这就是著名的 GAPS 和 ISLANDS 问题。您可以阅读 this wonderful article from Lalit Kumar B 了解详细说明。您可以尝试以下查询 -
SELECT id, MIN(value), MAX(value)
FROM (SELECT id, value, value - ROW_NUMBER() OVER(PARTITION BY id ORDER BY value) rn
FROM test) T
GROUP BY id, rn;
这是Fiddle
如果您从值本身中减去每个值在该 ID 的值列表中的位置(您可以使用分析函数获得):
value - dense_rank() over (partition by id order by value)
那么连续(或重复)的值将得到相同的结果:
select id, value,
value - dense_rank() over (partition by id order by value)
from your_table;
ID VALUE GRP
---------- ---------- ----------
1 5 4
1 6 4
1 8 5
1 9 5
1 10 5
然后您可以使用这些差异进行汇总:
select id, min(value) as minvalue, max(value) as maxvalue
from (
select id, value,
value - dense_rank() over (partition by id order by value) as grp
from your_table
)
group by id, grp
order by id, minvalue;
ID MINVALUE MAXVALUE
---------- ---------- ----------
1 5 6
1 8 10
如果没有重复,您可以使用 row_number()
instead of dense_rank()
。