Пробелы при объединении нескольких столбцов и одного столбца равно null-Oracle

Мне нужно объединить несколько столбцов в один, с пробелами между каждым значением. Проблема в том, что когда одно значение равно null, я получаю двойное пространство между двумя значениями.

пример

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

если второе имя имеет значение NULL, то я получаю два пробела между первым и последним именем. Любой способ обойти это и иметь только одно пространство, когда есть нулевое значение?

9 ответов


другой вариант-использовать decode:

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

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

из документации Oracle:

CONCAT_WS(сепаратор,str1 выглядит следующим образом,стр2,...)

CONCAT_WS () означает Конкатенат с разделителем и является специальным форма CONCAT(). Первый аргумент является разделителем для остальной части аргумент. Разделитель добавляется между строками конкатенированный. Разделитель может быть строкой, как и остальная часть аргументы. Если разделитель равен NULL, результат равен NULL.

и очень важный комментарий:

CONCAT_WS() не пропускает пустые строки. Однако он пропускает любые Значения NULL после аргумента separator.

поэтому в вашем случае это должно быть:

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

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;

можно использовать 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 к строке возвращает исходную строку.


вот как я обычно объединяю несколько полей и удаляю пробелы в Oracle:

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

  1. объедините все необходимые поля с пробелом между ними. Пустые строки и значения NULL приведут к двум или более пробелам;
  2. используйте регулярное выражение для изменения любых вхождений нескольких пространств [ ' + ' ] в одно пространство [''];
  3. наконец, обрезать пробелы в начале и/или конце из полученного строка.

еще один вариант:

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

или вы можете просто использовать функцию 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 за данные примера: -)


У меня есть эта работа с Пример. Надеюсь, это поможет. Просто перейдите в 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