Sql 在Oracle中汇总空行

Sql 在Oracle中汇总空行,sql,oracle,oracle11g,Sql,Oracle,Oracle11g,我有这样一个数据集: +---------------+-------+ | SAMPLE_NUMBER | SCORE | +---------------+-------+ | 1 | 100 | | 2 | 97 | | 3 | 124 | | 4 | 762 | | 5 | 999 | | 6 | 1200 | |

我有这样一个数据集:

+---------------+-------+
| SAMPLE_NUMBER | SCORE |
+---------------+-------+
|             1 | 100   |
|             2 | 97    |
|             3 | 124   |
|             4 | 762   |
|             5 | 999   |
|             6 | 1200  |
|             7 | NULL  |
|             8 | NULL  |
|             9 | NULL  |
|            10 | NULL  |
+---------------+-------+
+---------------+-------+
| SAMPLE_NUMBER | SCORE |
+---------------+-------+
| 1             | 100   |
| 2             | 97    |
| 3             | 124   |
| 4             | 762   |
| 5             | 999   |
| 6             | 1200  |
| 7-10          | NULL  |
+---------------+-------+
我希望能够汇总空行,而不是全部显示它们。因此,理想情况下,我希望上述情况如下所示:

+---------------+-------+
| SAMPLE_NUMBER | SCORE |
+---------------+-------+
|             1 | 100   |
|             2 | 97    |
|             3 | 124   |
|             4 | 762   |
|             5 | 999   |
|             6 | 1200  |
|             7 | NULL  |
|             8 | NULL  |
|             9 | NULL  |
|            10 | NULL  |
+---------------+-------+
+---------------+-------+
| SAMPLE_NUMBER | SCORE |
+---------------+-------+
| 1             | 100   |
| 2             | 97    |
| 3             | 124   |
| 4             | 762   |
| 5             | 999   |
| 6             | 1200  |
| 7-10          | NULL  |
+---------------+-------+

Oracle有没有办法做到这一点?或者这是我在查询后必须做的事情?

是的。对于您的示例数据:

select (case when score is null then min(sample_number) || '-' || max(sample_number)
             else min(sample_number)
        end) as sample_number,
       score
from table t
group by score
order by min(id)
换句话说,
按分数分组,然后修改样本编号。注意:这假设您没有重复的分数。如果这样做,可以使用更复杂的版本:

select (case when score is null then min(sample_number) || '-' || max(sample_number)
             else min(sample_number)
        end) as sample_number,
       score
from (select t.*,
             row_number() over (partition by score order by sample_number) as seqnum
      from table t
     ) t
group by score, (case when score is not null then seqnum end);

我的猜测是,这应该是表示层的一部分,因为您必须将示例编号转换为字符串(假设它是数字类型)。替代您的要求的另一种方法是返回最小和最大连续示例编号:

with t (SAMPLE_NUMBER, SCORE) as (
    values  (1, 100)
        ,   (2, 97)
        ,   (3, 124)
        ,   (4, 762)
        ,   (5, 999)
        ,   (6, 1200)
        ,   (7, NULL)
        ,   (8, NULL)
        ,   (9, NULL)
        ,   (10, NULL)
)
select min(sample_number), max(sample_number), grp, score
from (
    select SAMPLE_NUMBER, SCORE
       ,   row_number() over (order by SAMPLE_NUMBER)
       -   row_number() over (partition by SCORE
                              order by SAMPLE_NUMBER) as grp
    from t
) group by grp, score
order by grp;

1           2           GRP                  SCORE      
----------- ----------- -------------------- -----------
      1           1                    0         100
      2           2                    1          97
      3           3                    2         124
      4           4                    3         762
      5           5                    4         999
      6           6                    5        1200
      7          10                    6           -
尝试使用db2,因此您可能需要稍微调整它

编辑:当分数不为空时,将行视为单个行

with t (SAMPLE_NUMBER, SCORE) as (
    values  (1, 100)
        ,   (2, 97)
        ,   (3, 97)
        ,   (4, 762)
        ,   (5, 999)
        ,   (6, 1200)
        ,   (7, NULL)
        ,   (8, NULL)
        ,   (9, NULL)
        ,   (10, NULL)
)
select min(sample_number), max(sample_number), grp, score
from (
    select SAMPLE_NUMBER, SCORE
       ,   row_number() over (order by SAMPLE_NUMBER)
       -   row_number() over (partition by SCORE
                              order by SAMPLE_NUMBER) as grp
    from t
) group by grp, score
         , case when score is not null then sample_number end
order by grp;

1           2           GRP                  SCORE      
----------- ----------- -------------------- -----------
      1           1                    0         100
      2           2                    1          97
      3           3                    1          97
      4           4                    3         762
      5           5                    4         999
      6           6                    5        1200
      7          10                    6           -
如果最大值与最小值相同,则可能需要将最大值映射为null:

[...]
select min(sample_number)
     , nullif(max(sample_number), min(sample_number))
     , grp
     , score
from ...

1           2           GRP                  SCORE      
----------- ----------- -------------------- -----------
      1           -                    0         100
      2           -                    1          97
      3           -                    1          97
      4           -                    3         762
      5           -                    4         999
      6           -                    5        1200
      7          10                    6           -

猜测一下:使用联合是有用的,第一部分没有空值,第二部分有一个格式化的记录,不要忘记数据类型。谢谢你的回答-这在大多数情况下都有效,但如果有重复的分数就不行了。如果有重复的分数,我们怎么做?假设
update t set score=97,其中sample_number=3
。结果应该是什么样的?当前查询返回min=2,max=3,score=97,您的预期输出是什么?我希望它返回min=3,max=3,score=97您是否还希望2,2,97有一行,还是希望跳过该行?是的,如果结果不为空,则应为所有结果返回一行