Oracle SQL查询将连续记录分组

时间:2013-12-09 01:08:48

标签: sql oracle analytics

我已将数据(“金额”和“旁白”)从电子表格导入到表格中,需要帮助查询根据“叙述”对连续记录进行分组,例如:

预期产出:

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!

1 个答案:

答案 0 :(得分:5)

尝试此查询:

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

演示 - &gt; http://www.sqlfiddle.com/#!4/6d7aa/9