3

我正在尝试从 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

这可能吗?

谢谢!

4

3 回答 3

7

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

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

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
)
于 2013-06-13T11:11:59.283 回答
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
于 2013-06-13T11:15:03.453 回答
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...您将获得下一条记录的group_id

使用case表达式,您将当前 group_id下一个一个进行比较,然后返回适当的值。

于 2013-06-13T11:33:38.857 回答