Oracle SQL 查询对连续记录进行分组
Posted
技术标签:
【中文标题】Oracle SQL 查询对连续记录进行分组【英文标题】:Oracle SQL query to group consecutive records 【发布时间】:2013-12-09 01:08:48 【问题描述】:我已将数据(“金额”和“旁白”)从电子表格导入到表格中,需要帮助查询以根据“旁白”对连续记录进行分组,例如:
预期输出:
line_no amount narration calc_group <-Not part of table
----------------------------------------
1 10 Reason 1 1
2 -10 Reason 1 1
3 5 Reason 2 2
4 5 Reason 2 2
5 -10 Reason 2 2
6 -8 Reason 1 3
7 8 Reason 1 3
8 11 Reason 1 3
9 99 Reason 3 4
10 -99 Reason 3 4
我尝试了一些分析函数:
select line_no, amount, narration,
first_value (line_no) over
(partition by narration order by line_no) "calc_group"
from test
order by line_no
但这不起作用,因为第 6 到 8 行的叙述与第 1 和 2 行相同。
line_no amount narration calc_group
----------------------------------------
1 10 Reason 1 1
2 -10 Reason 1 1
3 5 Reason 2 3
4 5 Reason 2 3
5 -10 Reason 2 3
6 -8 Reason 1 1
7 8 Reason 1 1
8 11 Reason 1 1
9 99 Reason 3 4
10 -99 Reason 3 4
更新
我已经设法使用滞后分析函数和序列来做到这一点,虽然不是很优雅,但它确实有效。应该有更好的方法,欢迎评论!
create or replace function get_next_test_seq
return number
as
begin
return test_seq.nextval;
end get_next_test_seq;
create or replace function get_curr_test_seq
return number
as
begin
return test_seq.currval;
end get_curr_test_seq;
update test
set group_no =
(with cte1
as (select line_no, amount, narration,
lag (narration) over (order by line_no) prev_narration, group_no
from test
order by line_no),
cte2
as (select line_no, amount, narration, group_no,
case when prev_narration is null or prev_narration <> narration then get_next_test_seq else get_curr_test_seq end new_group_no
from cte1)
select new_group_no
from cte2
where cte2.line_no = test.line_no);
更新 2
我对更好接受的答案感到满意。谢谢 kordiko!
【问题讨论】:
请提供预期的输出。你想达到什么目的?第 6 到 8 行中的Narration
与第 1 行和第 2 行中的相同,因为您按 Narration
的值进行分组,这对于这些记录是相同的。
预期的输出是我在第一个结果中指出的“calc_group”的值。我知道因为第 6 到 8 行的分组将与第 1 和 2 行具有相同的值,但我希望第 6 到 8 行具有不同的唯一值。
Kobus - 对这个逻辑的查询并不那么简单。看看我的一个问题。 ***.com/questions/17824432/…。您首先需要确定“叙述发生变化的地方”,然后在此基础上进行分析。
感谢 Rajesh,我已经使用延迟来确定“旁白发生变化的地方”。我用一个丑陋但有效的解决方案更新了我的问题
如果您的更新对您有用,请考虑将其发布为答案,以便寻找解决方案的人更容易找到它
【参考方案1】:
试试这个查询:
SELECT line_no,
amount,
narration,
SUM( x ) OVER ( ORDER BY line_no
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) as calc_group
FROM (
SELECT t.*,
CASE lag( narration ) OVER (order by line_no )
WHEN narration THEN 0
ELSE 1 END x
FROM test t
)
ORDER BY line_no
演示 --> http://www.sqlfiddle.com/#!4/6d7aa/9
【讨论】:
以上是关于Oracle SQL 查询对连续记录进行分组的主要内容,如果未能解决你的问题,请参考以下文章
在 SQL (Redshift) 中对连续块进行分组以进行聚合