Oracle 11g:仅当行在组中的第一个或最后一个时才返回值

时间:2013-06-13 10:58:05

标签: sql oracle oracle11g

我正在尝试从Oracle查询创建报告。数据是这样的:

GROUP_ID | COUNT_1 | COUNT_2
    1    |   100   |   123
    1    |   101   |   123
    1    |   283   |   342
    1    |   134   |   123
    2    |   241   |   432
    2    |   321   |   920
    2    |   432   |   121
    2    |   135   |   342

我想要做的只是当它在组中的第一个时返回GROUP_ID,以及当它在组中的最后一个时返回一些其他值,例如

GROUP_ID | COUNT_1 | COUNT_2
    1    |   100   |   123
         |   101   |   123
         |   283   |   342
   last  |   134   |   123
    2    |   241   |   432
         |   321   |   920
         |   432   |   121
   last  |   135   |   342

这可能吗?

谢谢!

3 个答案:

答案 0 :(得分:7)

未经测试,但这应该是主意。如果您需要按COUNT_1或COUNT_2排序,则应将其包含在分析函数“over子句partition by GROUP_ID order by COUNT_1

请参阅here以了解分析函数是什么。

select
  case when ROW_NUMBER = 1 then GROUP_ID
       when ROW_NUMBER = GROUP_COUNT then 'last'
       else NULL
  end GROUP_ID
  ,COUNT_1
  ,COUNT_2
from(
    select
      GROUP_ID
      ,COUNT_1
      ,COUNT_2
      ,row_number() over(partition by GROUP_ID) ROWNUMBER
      ,count(GROUP_ID) over (partition by GROUP_ID) GROUP_COUNT
    from
      FOO
)

答案 1 :(得分:3)

CREATE TABLE tt(g NUMBER, c1 NUMBER, c2 NUMBER);
INSERT INTO tt VALUES(1, 100, 123);
INSERT INTO tt VALUES(1, 101, 123);
INSERT INTO tt VALUES(1, 283, 342);
INSERT INTO tt VALUES(1, 134, 123);
INSERT INTO tt VALUES(2, 241, 432);
INSERT INTO tt VALUES(2, 321, 920);
INSERT INTO tt VALUES(2, 432, 121);
INSERT INTO tt VALUES(2, 135, 342);

SELECT CASE WHEN 1=ROW_NUMBER() OVER (PARTITION BY g ORDER BY c1 ASC,  c2 ASC) THEN '1'
            WHEN 1=ROW_NUMBER() OVER (PARTITION BY g ORDER BY c1 DESC, c2 DESC) THEN 'Last'
            ELSE 'Empty'
        END answer,
       c1, c2
  FROM tt;

1        100  123
Empty    101  123
Empty    134  123
Last     283  342
1        135  342
Empty    241  432
Empty    321  920
Last     432  121

答案 2 :(得分:1)

您可以尝试使用lag()lead()分析函数:

with a as (
   select 1 group_id, 100 count_1, 123 count_2 from dual union all
   select 1 group_id, 101 count_1, 123 count_2 from dual union all
   select 1 group_id, 283 count_1, 342 count_2 from dual union all
   select 1 group_id, 134 count_1, 123 count_2 from dual union all
   select 2 group_id, 241 count_1, 432 count_2 from dual union all
   select 2 group_id, 321 count_1, 920 count_2 from dual union all
   select 2 group_id, 432 count_1, 121 count_2 from dual union all
   select 2 group_id, 135 count_1, 342 count_2 from dual 
)
select
  case lag (group_id) over (order by group_id, count_1) 
    when group_id then 
      case lead (group_id) over (order by group_id, count_1)
      when group_id then null
           else 'last'
      end
    else to_char(group_id) end x,
  count_1,
  count_2
from
a;

lag(group_id) over (order by group_id, count_1)您获得之前记录的group_id(它落后)。同样,使用lead(group_id) over...,您将获得 next 记录的group_id。

使用case表达式,将当前 group_id next previous 进行比较,然后返回适当的值。