在oracle中获取序列组的第一个和最后一个

时间:2015-01-07 05:19:15

标签: sql oracle select serialization group-by

我试图从表中选择(已排序):

+--------+-------+
| Serial | Group |
+--------+-------+
| 0100   | 99    |
| 0101   | 99    |
| 0102   | 99    |
| 096    | 92    |
| 097    | 92    |
| 099    | 93    |
| 23     | 16    |
| 95     | 87    |
| 99     | 90    |
| 100    | 90    |
| 101    | 90    |
| 102    | 90    |
| a      | a     |
| b      | b     |
| c      | c     |
+--------+-------+

我希望表(第一个,最后一个,按组分组):fsdfsdfsdfdsfsdf

+------------+----------+----------+
| fromSerial | toSerial | quantity |
+------------+----------+----------+
| 0100       | 0102     |        3 |
| 096        | 097      |        2 |
| 099        | 099      |        1 |
| 99         | 102      |        4 |
| 23         | 23       |        1 |
| 95         | 95       |        1 |
| a          | a        |        1 |
| b          | b        |        1 |
| c          | c        |        1 |
+------------+----------+----------+

我的查询

感谢。

3 个答案:

答案 0 :(得分:0)

您可以使用窗口分析函数row_number根据group列对数据进行分区 您还可以获得每个分区中的元素数量 然后,您可以case based aggregation获取fromto序列号值。

SQL Fiddle Demo

with cte
as
(
select "Serial", "Group",  row_number() over ( partition by "Group" order by "Serial" ) as rn,
          count(*) over ( partition by "Group") as cnt
from Table1
)
select max(case when rn =1 then "Serial" end) as "FromSerial",
       max(case when rn =cnt then "Serial" end) as "ToSerial",
       max(cnt) as quantity
from cte
group by "Group"

答案 1 :(得分:0)

尝试此查询:

SELECT grp,
       Cast(Min(Cast(serial AS INT)) AS VARCHAR2(30)) fromserial,
       Cast(Max(Cast(serial AS INT)) AS VARCHAR2(30)) toserial,
       Count(*)                                       quantity
FROM   yourtable
WHERE  NVL(LENGTH(TRIM(TRANSLATE(serial, '0123456789', ' '))), 0) = 0
GROUP  BY grp
UNION
SELECT grp,
       Cast(Min(serial) AS VARCHAR2(30)) fromserial,
       Cast(Max(serial) AS VARCHAR2(30)) toserial,
       Count(*)                          quantity
FROM   yourtable
WHERE  NVL(LENGTH(TRIM(TRANSLATE(serial, '0123456789', ' '))), 0) != 0
GROUP  BY grp
ORDER  BY grp 

Sqlfiddle

答案 2 :(得分:0)

使用MINMAXGROUP BY

并且,请勿使用关键字GROUP作为列名。

SQL> WITH DATA AS(
  2  SELECT '0100'  Serial,  '99' "GROUP_1"   FROM dual UNION ALL
  3  SELECT  '0101' ,   '99'     FROM dual UNION ALL
  4   SELECT '0102' ,  '99'     FROM dual UNION ALL
  5   SELECT '096' ,    '92'     FROM dual UNION ALL
  6   SELECT '097' ,    '92'      FROM dual UNION ALL
  7   SELECT '099',     '93'      FROM dual UNION ALL
  8   SELECT '23'  ,    '16'      FROM dual UNION ALL
  9   SELECT '95'  ,    '87'     FROM dual UNION ALL
 10   SELECT '99'  ,    '90'     FROM dual UNION ALL
 11   SELECT '100' ,    '90'    FROM dual UNION ALL
 12   SELECT '101' ,    '90'    FROM dual UNION ALL
 13   SELECT '102' ,    '90'     FROM dual UNION ALL
 14   SELECT 'A' ,       'A'      FROM dual UNION ALL
 15   SELECT 'b'  ,     'b'      FROM dual UNION ALL
 16   SELECT 'c'  ,     'c'     FROM dual
 17   )
 18  SELECT MIN(serial) fromserial,
 19    MAX(Serial) toserial,
 20    COUNT(*) quantity
 21  FROM DATA
 22  GROUP BY group_1
 23  ORDER BY fromserial
 24  /

FROM TOSE   QUANTITY
---- ---- ----------
0100 0102          3
096  097           2
099  099           1
100  99            4
23   23            1
95   95            1
A    A             1
b    b             1
c    c             1

9 rows selected.

SQL>