在oracle中连接值

时间:2015-03-12 06:12:18

标签: sql oracle string-concatenation

我必须使用' - '连接列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

请建议我们能否以其他方式实施此逻辑

3 个答案:

答案 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