使用Oracle SQL 10.2进行顺序分组

时间:2014-09-30 08:56:15

标签: sql oracle

我正在努力选择一些SQL并需要你的帮助。 我正在处理这类数据:

key1    key2    key3    id  attr
550928  *   *   5   2225
550928  *   *   6   4060
550928  *   *   10  7125
550928  *   *   20  7105
550928  *   *   22  2220
550928  *   *   25  7125
550928  *   *   30  7110
550928  *   *   35  7110
550928  *   *   40  7110
550928  *   *   50  7110
550928  *   *   60  7110
550928  *   *   70  7110
550928  *   *   80  7110
550928  *   *   90  7110
550928  *   *   100 7110
550928  *   *   110 7110
550928  *   *   115 7110
550928  *   *   120 7110
550928  *   *   130 7110
550928  *   *   140 7110
550928  *   *   150 7110
550928  *   *   155 7110
550928  *   *   170 2220
550928  *   *   190 4160
550928  *   *   210 4160
550928  *   *   220 2225
550928  *   *   225 2220
550928  *   *   999 2220

我想得的是这样的

key1    key2    key3    id  attr
550928  *   *   5   2225
550928  *   *   6   4060
550928  *   *   10  7125
550928  *   *   20  7105
550928  *   *   22  2220
550928  *   *   25  7125
550928  *   *   30 - 155    7110
550928  *   *   170 2220
550928  *   *   190  - 210  4160
550928  *   *   220 2225
550928  *   *   225 - 999   2220

所以要按顺序在attr上进行分组,但是一行一行,而不是在整个集合中。 我试过这样的事情,但它似乎没有按计划运作:

select key1,
       key2,
       key3,
       attr,
       min_id,
       max_id
  from (select soo.key1,
               soo.key2,
               soo.key3,
               soo.attr,
               soo.id,
               min(soo.id) keep(dense_rank first order by soo.key1, soo.key2, soo.key3, lpad(soo.id, 5, '0')) over(partition by soo.key1, soo.key2, soo.key3, soo.attr) min_id,
               max(soo.id) keep(dense_rank last order by soo.key1, soo.key2, soo.key3, lpad(soo.id, 5, '0')) over(partition by soo.key1, soo.key2, soo.key3, soo.attr) max_id
          from my_table soo)
 where (id = min_id or id = max_id)
 order by min_id;

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

可能有所帮助,但未经测试:

SELECT key1,
       key2,
       key3,
       attr,
       min(id) min_id,
       max(id) max_id
  FROM my_table
 GROUP
    BY key1, 
       key2, 
       key3, 
       attr
 ORDER
    BY 5

答案 1 :(得分:0)

尝试使用row_number():

SELECT KEY,
     CASE WHEN MIN(ID) = MAX(ID) 
          THEN TO_CHAR(MIN(ID)) 
          ELSE MIN(ID)||'-'||MAX(ID) 
     END AS grouped_id,
     attr
FROM
     (SELECT key,id,attr,
          row_number() OVER( ORDER BY ID) - row_number() OVER( PARTITION BY attr ORDER BY ID) grp
     FROM your_table
     )
GROUP BY KEY, attr, grp
ORDER BY MIN(id);

您将得到如下结果:

key    grouped_id attr
----------------------
550928  5         2225
550928  6         4060
550928  10        7125
550928  20        7105
550928  22        2220
550928  25        7125
550928  30-155    7110
550928  170       2220
550928  190-210   4160
550928  220       2225
550928  225-999   2220