我必须使用' - '连接列a,b,c。像a-b-c。如果a或b或c为null,那么我们不应该考虑此列值。
示例:
select A,B,C,
case
when A is not null and B is not null and C is not null then
A ||'-'||B ||'-'|| C
when A is not null and B is not null then
A||'-'||B
when A is not null and C is not null then
A||'-'||C
when B is not null and C is not null then
B||'-'||C
when A is null and B is null and C is not null then
C
when A is null and C is null and B is not null then
B
when B is null and C is null and A is not null then
A
end
TEXT from
table1
请建议我们能否以其他方式实施此逻辑
答案 0 :(得分:2)
你不必太复杂。 NULL 无论如何都是隐式处理的,不会被考虑,你只需要处理你用来连接字符串的分隔符。 TRIM 应该可以胜任。
SQL> WITH DATA AS(
2 SELECT 1 A, 2 b, 3 c FROM dual UNION ALL
3 SELECT NULL A, NULL b, NULL c FROM dual UNION ALL
4 SELECT 1 A, NULL b, NULL c FROM dual UNION ALL
5 SELECT 1 A, 2 b, NULL c FROM dual
6 )
7 SELECT TRIM(both '-' FROM A||'-'||b||'-'||c) str FROM DATA;
STR
----------------------------------------------------------------
1-2-3
1
1-2
SQL>
如果要排除NULL值,请在谓词中添加 NOT NULL 过滤器。
SQL> WITH DATA AS(
2 SELECT 1 A, 2 b, 3 c FROM dual UNION ALL
3 SELECT NULL A, NULL b, NULL c FROM dual UNION ALL
4 SELECT 1 A, NULL b, NULL c FROM dual UNION ALL
5 SELECT 1 A, 2 b, NULL c FROM dual
6 )
7 SELECT str
8 FROM
9 ( SELECT TRIM(BOTH '-' FROM A||'-'||b||'-'||c) str FROM DATA
10 )
11 WHERE str IS NOT NULL;
STR
-------------------------------------------------------------------
1-2-3
1
1-2
SQL>
当中间列为NULL且其他列不为空时,更新情况。
SQL> WITH DATA AS(
2 SELECT 1 A, 2 b, 3 c FROM dual UNION ALL
3 SELECT NULL A, NULL b, NULL c FROM dual UNION ALL
4 SELECT 1 A, NULL b, NULL c FROM dual UNION ALL
5 SELECT 1 A, 2 b, NULL c FROM dual UNION ALL
6 SELECT 1 A, NULL b, 3 c FROM dual
7 )
8 SELECT REPLACE(str, '--', '-') str
9 FROM
10 ( SELECT TRIM(BOTH '-' FROM A||'-'||b||'-'||c) str FROM DATA
11 )
12 WHERE str IS NOT NULL;
STR
-------------------------------------------------------------------
1-2-3
1
1-2
1-3
SQL>
答案 1 :(得分:1)
更通用的解决方案是为此编写一个函数:
CREATE OR REPLACE TYPE VARCHAR_TABLE_TYPE AS TABLE OF VARCHAR2(1000);
CREATE OR REPLACE FUNCTION JoinTable(
TAB IN VARCHAR_TABLE_TYPE,
Joiner IN VARCHAR2 DEFAULT '-') RETURN VARCHAR2 IS
res VARCHAR2(30000);
BEGIN
IF TAB IS NULL THEN
RETURN NULL;
END IF;
IF TAB.COUNT = 0 THEN
RETURN NULL;
END IF;
FOR i IN TAB.FIRST..TAB.LAST LOOP
IF TAB(i) IS NOT NULL THEN
res := res ||Joiner||TAB(i);
END IF;
END LOOP;
RETURN REGEXP_REPLACE(res, '^'||Joiner);
END JoinTable;
SELECT JoinTable(VARCHAR_TABLE_TYPE(A,B,C)) from Table1;
答案 2 :(得分:1)
为什么不使用函数nvl2?
select rtrim(nvl2(a, a||'-', '')||nvl2(b, b||'-', '')||nvl2(c, c, ''), '-') from table1
测试:
with table1 as(
select 'A' a, 'B' b, 'C' c from dual union all
select 'A', null, 'C' from dual union all
select null, null, 'C' from dual union all
select null, null, null from dual union all
select null, 'B', null from dual union all
select 'A', null, null from dual
)
select rtrim(nvl2(a, a||'-', '')||nvl2(b, b||'-', '')||nvl2(c, c, ''), '-') col
from table1
结果:
COL
-----
A-B-C
A-C
C
B
A
6 rows selected