连接多个列和一列时的空格为空 - Oracle

时间:2012-08-14 16:36:09

标签: oracle null concatenation space

我需要将多个列连接成一个列,每个值之间有空格。问题是当一个值为null时,我最终得到两个值之间的双倍空格。

实施例

SELECT (FIRST_NAME || ' ' || MIDDLE_NAME || ' ' || LAST_NAME
  FROM TABLE_A;

如果中间名恰好是NULL,那么我最后在名字和姓氏之间有两个空格。有什么方法可以解决这个问题,当有空值时只有一个空格?

10 个答案:

答案 0 :(得分:8)

SELECT TRIM(TRIM(FIRST_NAME || ' ' || MIDDLE_NAME) || ' ' || LAST_NAME)   
FROM TABLE_A; 

答案 1 :(得分:5)

来自Oracle的文档:

  

CONCAT_WS(分离器,STR1,STR2,...)

     

CONCAT_WS()代表Concatenate With Separator,是一个特殊的   形式的CONCAT()。第一个参数是其余部分的分隔符   争论。在字符串之间添加分隔符   级联。分隔符可以是字符串,其余部分也可以   参数。如果分隔符为NULL,则结果为NULL。

非常重要的评论:

  

CONCAT_WS()不会跳过空字符串。但是,它确实跳过了   分隔符参数后的NULL值。

所以在你的情况下它应该是:

CONCAT_WS(',', FIRST_NAME, MIDDLE_NAME, LAST_NAME);

答案 2 :(得分:3)

with indata as
(
select 'John' as first_name, 'W' as middle_name, 'Smith ' as last_name from dual
union
select null as first_name, null as middle_name, 'Adams' as last_name from dual
union
select 'Tom' as first_name, null as middle_name, 'Jefferson' as last_name from dual
)
select
regexp_replace(trim(indata.first_name || ' ' || indata.middle_name || ' ' || indata.last_name), '\s{2,}', ' ')
from indata;

答案 3 :(得分:1)

您可以使用RPAD()添加空格字符:

SELECT RPAD(first_name, LENGTH(first_name)+1, ' ')||RPAD(middle_name, LENGTH(middle_name)+1, ' ')||last_name
FROM TABLE_A;

RPAD的任何参数为NULL时,结果将为NULL,并且在Oracle中为字符串附加NULL将返回原始字符串。

答案 4 :(得分:1)

这就是我通常连接几个字段并删除Oracle中的空格的方法:

TRIM(REGEXP_REPLACE(HOUSE_NO || ' ' || PREFIX || ' ' || STREET_NAME || ' ' || STREET_TYPE || ' ' || SUFFIX, ' +', ' '))

  1. 连接所有必要的字段,每个字段之间有一个空格。空字符串和NULL值将产生两个或多个空格;
  2. 使用正则表达式更改多个空格的出现次数[' +']到一个空间['] '];
  3. 最后,在结果字符串的开头和/或结尾处修剪任何空格。

答案 5 :(得分:0)

另一个选择是使用decode:

SELECT decode(FIRST_NAME,'','',FIRST_NAME ||' ') ||
       decode(MIDDLE_NAME,'','',MIDDLE_NAME ||' ') || LAST_NAME
FROM TABLE_A;

答案 6 :(得分:0)

又一个选择:

SELECT first_name
       || DECODE(middle_name
          ,      NULL, NULL
          ,      ' ' || middle_name)
       || DECODE(last_name
          ,      NULL, NULL
          ,      ' ' || last_name) full_name
FROM   table_a
;

答案 7 :(得分:0)

或者你可以简单地使用REPLACE函数:

with indata as 
  (select 'John' as first_name, 'W' as middle_name, 'Smith ' as last_name from dual 
   union 
   select null as first_name, null as middle_name, 'Adams' as last_name from dual 
    union 
    select 'Tom' as first_name, null as middle_name, 'Jefferson' as last_name from dual) 
SELECT REPLACE(TRIM(indata.first_name || ' ' || indata.middle_name || ' ' || indata.last_name), '  ', ' ')
  FROM indata

(感谢@tbone的示例数据: - )

答案 8 :(得分:0)

我通过示例解决了这个问题。希望这可以帮助。只需转到SQL Server,选择新查询并在查询后选择CP:

DECLARE @NULL_SAMLES TABLE
       (
       NS_ID INT IDENTITY(1,1) PRIMARY KEY CLUSTERED NOT NULL
      ,COL_01 VARCHAR(10) NULL
      ,COL_02 VARCHAR(10) NULL
      ,COL_03 VARCHAR(10) NULL
      ,COL_04 VARCHAR(10) NULL
   )

   INSERT INTO @NULL_SAMLES(COL_01,COL_02,COL_03,COL_04)
   VALUES
    ('A','B','C','D')
   ,(' ' ,'B','C','D')
   ,(' ',NULL,'C','D')
   ,('A','B',NULL,'D')
   ,('A','B','C',NULL)
   ,(NULL,'B',NULL,'D')
   ,(NULL,'B','C',NULL)
   ,('A',NULL,'C',NULL)
   ,('A',NULL,NULL,'D')
   ,('A',NULL,NULL,NULL)
   ,(NULL,'B',NULL,NULL)
   ,(NULL,NULL,'C',NULL)
   ,(NULL,NULL,NULL,'D')


   SELECT
        NS.COL_01
       ,NS.COL_02
       ,NS.COL_03
       ,NS.COL_04,
      Stuff(  
        Coalesce(', ' + nullif(NS.COL_01, ''), '') 
      + Coalesce(', ' + nullif(NS.COL_02, ''), '') 
      + Coalesce(', ' + nullif(NS.COL_03, ''), '') 
      +Coalesce(', ' + nullif(NS.COL_04, ''), '')
      , 1, 1, '') AS CONC_COLS
   FROM @NULL_SAMLES NS

答案 9 :(得分:0)

不要低估CASE语句的简单功能,可以将其连接起来。这是一个可以按原样运行的独立示例:

SELECT
CASE WHEN x.FIRST_NAME IS NULL THEN x.FIRST_NAME ELSE x.FIRST_NAME || ' ' END || 
CASE WHEN x.MIDDLE_NAME IS NULL THEN x.MIDDLE_NAME ELSE x.MIDDLE_NAME  || ' ' END || 
x.LAST_NAME
FROM (SELECT 'John' AS FIRST_NAME, NULL AS MIDDLE_NAME, 'Doe' AS LAST_NAME FROM DUAL) x;