我有一个示例表,如下所示:
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'值和逗号后面跟有两个以上列的&符号。
答案 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)
以下查询按您的预期界定..
键最后一次出现comma
被AND
取代。
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