Oracle / SQL - 需要在每行中从字符串中选择最大值的查询

时间:2017-06-26 16:53:42

标签: sql oracle

我需要一种优雅的方法来从包含逗号分隔列表的字段中选择最大值。

Expected Values:

List_1 | Last
------ | ------
A,B,C  | C   
B,D,C  | D 

我正在使用以下查询,但我没有得到预期的结果。

select
   list_1,
   (
      select max(values) WITHIN GROUP (order by 1) 
      from (
         select
            regexp_substr(list_1,'[^,]+', 1, level) as values
         from dual
         connect by regexp_substr(list_1, '[^,]+', 1, level) is not null)
   ) as last
from my_table

任何人都有任何想法来修复我的查询?

1 个答案:

答案 0 :(得分:1)

with
     test_data ( id, list_1 ) as (
       select 101, 'A,B,C' from dual union all
       select 102, 'B,D,C' from dual union all
       select 105, null    from dual union all
       select 122, 'A'     from dual union all
       select 140, 'A,B,B' from dual
     )
-- end of simulated table (for testing purposes only, not part of the solution)
select   id, list_1, max(token) as max_value
from     ( select id, list_1, 
                  regexp_substr(list_1, '([^,])(,|$)', 1, level, null, 1) as token
           from   test_data
           connect by level <= 1 + regexp_count(list_1, ',')                  
                  and prior id = id
                  and prior sys_guid() is not null
         )
group by id, list_1
order by id
;

  ID LIST_1_ MAX_VAL
---- ------- -------
 101 A,B,C   C    
 102 B,D,C   D    
 105            
 122 A       A    
 140 A,B,B   B  

在Oracle 12.1或更高版本中,可以使用LATERAL子句重写:

select   d.id, d.list_1, x.max_value
from     test_data d,
         lateral ( select max(regexp_substr(list_1, '([^,]*)(,|$)',
                                            1, level, null, 1)) as max_value
                   from   test_data x
                   where  x.id = d.id
                   connect by level <= 1 + regexp_count(list_1, ',')
                 ) x
order by d.id
;