Oracle SQL:至少选择前n行,继续直到列值与最后一行不同
给定以下结构的表 foo (Oracle 11g):
ID | GROUP_ID
1 | 100
2 | 100
3 | 100
4 | 200
5 | 300
6 | 300
7 | 400
我想选择前 n 行(按 ID 排序)或更多,这样我总是能得到一个完整的组。
示例:
n = 2:我想至少获取前两行,但由于 ID 3 也属于组 100,所以我也想获取它。
n = 4:给我前四行,我很高兴;-)
n = 5:请求第 1-6 行。
非常感谢您的帮助!
given a table foo of the following structure (Oracle 11g):
ID | GROUP_ID
1 | 100
2 | 100
3 | 100
4 | 200
5 | 300
6 | 300
7 | 400
I want to select the first n rows (ordered by ID) or more, such that I always get a complete group.
Example:
n = 2: I want to get at least the first two rows, but since ID 3 also belongs to group 100, I want to get that as well.
n = 4: Give me the first four rows and I am happy ;-)
n = 5: Rows 1-6 are requested.
Your help is highly appreciated!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
使用
rank()
的解决方案:构建测试数据:
运行...
编辑 这是包含
for update
子句的版本 (:n = 2 ):Solution using
rank()
:Building test data:
Running...
EDIT Here is version that includes the
for update
clause (:n = 2):如果
GROUP_ID
始终是连续且升序的,那么可以通过使用分析ROW_NUMBER()
函数的 SQL 轻松解决此问题:If it is always true that
GROUP_ID
is contiguous and ascending, then this is easily solved with SQL using an analyticalROW_NUMBER()
function:如果您的
ID
始终从 1 开始连续(无间隙)。并且如果您的Group_ID
从未在其他地方作为第二组出现。如果您的Group_ID
值始终在上升...您将受益于在
ID
和Group_ID
上建立单独的索引If your
ID
s are always sequential (without gaps) from 1. And if yourGroup_ID
s never occur as a second group elsewhere. And if yourGroup_ID
s are always ascending in value...You'll benefit here from having separate indexes on
ID
andGroup_ID
如果我们假设 group_id 是连续且升序的,那么@Shannon 的答案就完美。如果我们不做这个假设,并且我们有如下所示的数据,例如:
那么这是一个更棘手的问题。例如,如果N = 3、4或5,那么我们需要通过ID = 6获取行。对于N = 6,我们需要最多ID = 7。对于N = 7,我们需要通过ID = 11。
我相信无论 group_id 的顺序如何,此查询都有效:
For N = 7:
For N = 6:
For N = 1:
If we assume that the group_id's are contiguous and ascending, then @Shannon's answer works perfectly. If we do not make that assumption, and we have data that looks like this, for example:
Then it's a stickier problem. For example, if N = 3, 4, or 5, then we need to get the rows through ID = 6. For N = 6, we need up to ID = 7. For N = 7, we need through ID = 11.
I believe this query works regardless of the order of group_id:
For N = 7:
For N = 6:
For N = 1: