【问题标题】:Oracle SQL CaseOracle SQL 案例
【发布时间】:2018-11-29 04:52:50
【问题描述】:

我的查询:

select school, rating, name
from mytable
where school = 'SchoolN';

结果:

+--------+------+------+ |学校|评分|姓名| +--------+------+------+ |学校N | A |姓名1| |学校N | B |姓名2| |学校N | A |姓名3| |学校N | A |姓名4| |学校N | A |姓名5| |学校N | B |姓名6| |学校N | B |姓名7| |学校N | B |姓名8| |学校N | B |姓名9| +--------+------+------+

我想要的是这样命名:

+--------+------+---------+ |学校|评分|姓名| +--------+------+---------+ |学校N |一个 |i-Name1 | |学校N | B |我的名字2 | |学校N | A |ii-名称3 | |学校N | A |iii-姓名4| |学校N | A |iv-Name5 | |学校N | B |ii-名称6 | |学校N | B |iii-姓名7| |学校N | B |iv-Name8 | |学校N | B |v-Name9 | +--------+------+---------+

我试过了:

select school, rating,
case when rownum = 1 then 'i-' || name
     when rownum = 2 then 'ii-' || name
     when rownum = 3 then 'iii-' || name
     when rownum = 4 then 'iv-' || name
     when rownum = 5 then 'v-' || name
end Name
from mytable
where school = 'SchoolN';

但是结果是错误的:

+--------+------+---------+ |学校|评分|姓名| +--------+------+---------+ |学校N |一个 |i-Name1 | |学校N | B |ii-名称2 | |学校N | A |iii-姓名3| |学校N | A |iv-Name4 | |学校N | A |v-Name5 | |学校N | B |姓名6 | |学校N | B |姓名7 | |学校N | B |姓名8 | |学校N | B |姓名9 | +--------+------+---------+

【问题讨论】:

    标签: sql oracle oracle11g


    【解决方案1】:

    您可以在TO_CHAR 中使用罗马数字格式说明符RN

    SELECT
        level as n,
        TO_CHAR(level,'RN') as roman
    FROM
        dual
    CONNECT BY
        level <= 10;
    
    
             N ROMAN          
    ---------- ---------------
             1               I
             2              II
             3             III
             4              IV
             5               V
             6              VI
             7             VII
             8            VIII
             9              IX
            10               X
    
    10 rows selected. 
    

    所以,在 APC 的查询中,您可以使用 to_char(rn,'RN') || name as name

    【讨论】:

      【解决方案2】:

      ROWNUM 只是结果集中的行号。你真正想要的是每个ratingname 的数量。所以这意味着你需要一个像row_number()这样的分析函数:

      with cte as (
          select school, rating, name, 
                 row_number() over (partition by  school, rating order by name) as rn       
          from mytable
      )
      select cte.school, 
             cte.rating,
             case when cte.rn = 1 then 'i-' || name
                  when cte.rn = 2 then 'ii-' || name
                  when cte.rn = 3 then 'iii-' || name
                  when cte.rn = 4 then 'iv-' || name
                  when cte.rn = 5 then 'v-' || name
              end Name
      from cte
      where cte.school = 'SchoolN'
      ;
      

      这是生成所需结果集所需的对代码的最小更改。我建议你也合并@KaushikNayak 建议和deploy the rn format mask,因为这会让你的代码更紧凑,更不脆弱:

      ...
      select cte.school, 
             cte.rating,
             to_char(cte.rn, 'rn')|| '-' || name as Name
      from cte
      ...
      

      传递小写格式掩码 ('rn') 以获得小写输出:iii 等。

      【讨论】:

        【解决方案3】:

        你可以使用dense_rank()fmRM格式模型选项的字符转换功能(to_char):

        select t.school,
               t.rating,
               to_char(dense_rank() over(partition by rating order by name), 'fmrm') 
               || '-' ||t.name name
          from mytable t
         order by t.name;
        

        SQL Fiddle Demo

        【讨论】:

        • 你永远是一个很大的帮助先生!
        猜你喜欢
        • 1970-01-01
        • 2011-01-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-02-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多