oracle用户在sql中定义了分隔符

时间:2014-06-16 11:34:11

标签: sql oracle oracle11g

我有一个示例表,如下所示:

WITH T(ID, SLOW, MEDIUM, FAST, SUPER_FAST) AS
     (SELECT 1, 'Y', 'Y', 'N', 'Y' FROM DUAL
     UNION ALL
     SELECT 2, 'N','Y','N', 'Y' FROM DUAL
     )
SELECT 'Identified in '
||CASE WHEN L_TEXT_A IS NOT NULL THEN L_TEXT_A END ||' , '
||CASE WHEN L_TEXT_B IS NOT NULL THEN L_TEXT_B END ||' , '
||CASE WHEN L_TEXT_C IS NOT NULL THEN L_TEXT_C END ||' & '
||CASE WHEN L_TEXT_D IS NOT NULL THEN L_TEXT_D END
FROM
(
SELECT CASE WHEN slow = 'Y' THEN 'slow' END L_TEXT_A,
     CASE WHEN medium = 'Y' THEN 'medium' END L_TEXT_B,
     CASE WHEN FAST = 'Y' THEN 'fast' END L_TEXT_C,
     case when SUPER_FAST = 'Y' then 'super fast' END L_TEXT_D
FROM T
); --

Identified in slow , medium ,  & super fast                                                                                                                                                                                                                      
Identified in  , medium ,  & super fast 

我需要得到一个应该返回的结果:

'Identified in slow, medium and super fast'
'Identified in medium and super fast'

条件不是单列的分隔符,其中Y,&符号为' Y'值和逗号后面跟有两个以上列的&符号。

3 个答案:

答案 0 :(得分:3)

如果您使用的是Oracle 11g2,unpivot和listagg的组合可以提供帮助,请尝试此查询

WITH T(ID, SLOW, MEDIUM, FAST, SUPER_FAST) AS
     (SELECT 1, 'Y', 'Y', 'N', 'Y' FROM DUAL
     UNION ALL
     SELECT 2, 'N','Y','N', 'Y' FROM DUAL
     union all
     SELECT 3, 'N','N','N', 'Y' FROM DUAL
     union all 
     SELECT 4, 'N','N','N', 'N' FROM DUAL
     ),
tlist as (select listagg(speed, ', ') within group (order by rownum) as list, id
           from T
         unpivot (pace for speed in (SLOW as 'Slow',MEDIUM as 'Medium',  FAST as 'Fast', SUPER_FAST as 'Super Fast'))
          where pace = 'Y'
          group by id)
select case when instr(list, ', ', -1, 1) = 0 then 
            list
       else
            substr(list, 1, instr(list, ', ', -1, 1) - 1) || ' and ' || substr(list, instr(list, ', ', -1, 1) + 2)  
       end as  list
  from tlist;

输出:

|                        LIST |
|-----------------------------|
| Slow, Medium and Super Fast |
|       Medium and Super Fast |
|                  Super Fast |

答案 1 :(得分:1)

以下查询按您的预期界定..

最后一次出现commaAND取代。
regexp_count用于查找最后一次出现。

SQL> select regexp_replace('Identified in slow , medium , super fast',
               ',' ,' and ',1,
               regexp_count('Identified in slow , medium , super fast',',')) from dual;  2    3

REGEXP_REPLACE('IDENTIFIEDINSLOW,MEDIUM,SUPE
--------------------------------------------
Identified in slow , medium  and  super fast

完整版:

 WITH T(ID, SLOW, MEDIUM, FAST, SUPER_FAST) AS
     (SELECT 1, 'Y', 'Y', 'N', 'Y' FROM DUAL
     UNION ALL
     SELECT 2, 'N','Y','N', 'Y' FROM DUAL
     ),
mytext as 
(SELECT trim(trailing ',' FROM 'Identified in '
||NVL2(L_TEXT_A,L_TEXT_A||',',NULL)
||NVL2(L_TEXT_B,L_TEXT_B||',',NULL)
||NVL2(L_TEXT_C,L_TEXT_C||',',NULL)
||(L_TEXT_D)) as text
FROM
(
SELECT CASE WHEN slow = 'Y' THEN 'slow' END L_TEXT_A,
     CASE WHEN medium = 'Y' THEN 'medium' END L_TEXT_B,
     CASE WHEN FAST = 'Y' THEN 'fast' END L_TEXT_C,
     case when SUPER_FAST = 'Y' then 'super fast' END L_TEXT_D
FROM T
)
)
SELECT regexp_replace(text,
               ',' ,
               ' and ',
               1,
               regexp_count(text,',')) FROM mytext;

答案 2 :(得分:1)

这里有一些代码使用简单的instr,substr和replace函数,这些函数内置的函数似乎适用于所有组合。注意,如果您可以选择通过PL / SQL函数执行此操作,则可以稍微简化代码:

with t(id, slow, medium, fast, super_fast) as (
   select 1, 'n', 'n', 'n', 'n' from dual
   union all
   select 2, 'y', 'n', 'n', 'n' from dual
   union all
   select 3, 'n', 'y', 'n', 'n' from dual
   union all
   select 4, 'n', 'n', 'y', 'n' from dual
   union all
   select 5, 'n', 'n', 'n', 'y' from dual
   union all
   select 6, 'y', 'y', 'n', 'n' from dual
   union all
   select 7, 'y', 'n', 'y', 'n' from dual
   union all
   select 8, 'y', 'n', 'n', 'y' from dual
   union all
   select 9, 'n', 'y', 'y', 'n' from dual
   union all
   select 10, 'n', 'y', 'n', 'y' from dual
   union all
   select 11, 'n', 'n', 'y', 'y' from dual
   union all
   select 12, 'y', 'y', 'y', 'n' from dual
   union all
   select 13, 'y', 'y', 'n', 'y' from dual
   union all
   select 14, 'y', 'n', 'y', 'y' from dual
   union all
   select 15, 'n', 'y', 'y', 'y' from dual
   union all
   select 16, 'y', 'y', 'y', 'y' from dual
   ),
   step1 as (
   select 'identified in ' ||
          decode(slow,'y', 'slow' || ', ', '') ||
          decode(medium,'y', 'medium' || ', ', '') ||
          decode(fast,'y', 'fast' || ', ', '') ||
          decode(super_fast,'y', 'super fast' || ', ', '') str
     from t
   ),
   step2 as (
   select length(str) - length(replace(str, ',', null)) as vals, -- count values (using commas)
          substr(str, 1, length(str)-2) as str -- strip final comma
     from step1
   ),
   step3 as (
   select str,
          decode(vals, 0, 0, 1, 0, instr(str, ',', 1, vals -1)) as final_comma_pos,
          vals
     from step2
   ),
   step4 as (
   select decode(vals, 0, null,
                       1, str,
                          substr(str, 1, final_comma_pos - 1) || ' &' || 
                          substr(str, final_comma_pos + 1)
                ) as str
     from step3
   )
select * from step4;

输出:

identified in slow
identified in medium
identified in fast
identified in super fast
identified in slow & medium
identified in slow & fast
identified in slow & super fast
identified in medium & fast
identified in medium & super fast
identified in fast & super fast
identified in slow, medium & fast
identified in slow, medium & super fast
identified in slow, fast & super fast
identified in medium, fast & super fast
identified in slow, medium, fast & super fast