说select IDX, SUB_IDX, NAME from MYTABLE order by IDX, SUB_IDX
结果:
IDX SUB_IDX NAME
1 20 aaa
2 22 bbb
3 22 ccc
4 23 ddd
5 23 eee
6 23 fff
IDX
是PK,我希望计算连续SUB_IDX
的重复次数:
IDX SUB_IDX count NAME
1 20 1 aaa
2 22 1 bbb
3 22 2 ccc
4 23 1 ddd
5 23 2 eee
6 23 3 fff
我怎样才能做到这一点?
答案 0 :(得分:2)
我想你想要count
窗口函数:
select
idx, sub_idx,
count (1) over (partition by sub_idx order by idx) as count,
name
from MYTABLE
答案 1 :(得分:2)
我想计算重复 连续
SUB_IDX
由于您的 连续 要求,查询变得更加复杂。您的示例数据有点过于简单,并且没有清楚地显示出现非连续重复SUB_IDX
值时您的预期输出。
尽管如此,假设我正确理解,结合一些分析函数,它是可能的。也许有人可以找到简化查询的方法:
with grp_starts as (
select idx, sub_idx, name,
case when sub_idx = lag(sub_idx) over (order by idx)
then 0 else 1 end as is_grp_start
from mytable),
grps as (
select idx, sub_idx, name,
sum(is_grp_start) over (order by idx) as grp_id
from grp_starts)
select idx,
sub_idx,
row_number() over (partition by grp_id order by idx) as count,
name
from grps
答案 2 :(得分:2)
假设你的意思并不是“连续”(通过什么排序标准“连续”?)而是你只想将连续数字分配给具有相同SUB_INDEX的行......并假设你想要分配这些数字增加(按字母顺序)NAME的顺序:
select idx, sub_idx, row_number() over (partition by sub_idx order by name) as ct, name
from table_name
count是Oracle中的保留字;不要将它用作列名。 (与DATE,LAST等相同)
答案 3 :(得分:1)
为了完整起见,这是另一种解决方案,与sstan非常相似,但是使用了#tab; tabibitosan"或者"平等差异"创建组的方法(而不是"组的开始"方法,这是更一般的,但在这种情况下效率较低,因为它读取相同的行两次而不是一次)。
可以应用tabibitosan方法的一般问题类别被称为" gap and islands"问题,或在一个或多个列中找到具有相同值的连续行序列(根据一些明确指定的顺序)。
注意row_number()
子查询中对grps
的两次调用的不同 - 这取代了"组"用"组开始"创建标志后跟一个运行总和。另外,请注意一旦"组"通过形成行数的差异,在最后(外部)查询中使用的组由此差异sub_idx
,而不仅仅由row_number()
差异(这是对方法的常见误解)。
我提供了OTN"社区文档的链接"在对sstan的解决方案的评论中关于tabibitosan方法。
在某些情况下,当idx
是序列号(连续)时,可以使用row_number() over (order by idx)
本身而不是idx
。这是糟糕的编程,因为它依赖于特定的"物理"对数据的了解。我在下面写的解决方案不依赖于这些知识(为了演示,我添加了更多行,其中idx
不是连续数字)。
with
t ( idx, sub_idx, name ) as (
select 1, 20, 'aaa' from dual union all
select 2, 22, 'bbb' from dual union all
select 3, 22, 'ccc' from dual union all
select 4, 23, 'ddd' from dual union all
select 5, 23, 'eee' from dual union all
select 6, 23, 'fff' from dual union all
select 7, 22, 'ggg' from dual union all
select 9, 22, 'hhh' from dual union all
select 12, 20, 'iii' from dual union all
select 18, 20, 'jjj' from dual
),
grps ( idx, sub_idx, name, grp ) as (
select idx, sub_idx, name,
row_number() over (order by idx) -
row_number() over (partition by sub_idx order by idx)
from t
)
select idx, sub_idx,
row_number() over (partition by sub_idx, grp order by idx) as ct,
name
from grps
order by idx -- ORDER BY is optional
;
<强>输出强>:
IDX SUB_IDX CT NAME
---------- ---------- ---------- ----
1 20 1 aaa
2 22 1 bbb
3 22 2 ccc
4 23 1 ddd
5 23 2 eee
6 23 3 fff
7 22 1 ggg
9 22 2 hhh
12 20 1 iii
18 20 2 jjj
10 rows selected