Динамическая конкатенация с разделителем (игнорировать нули)

#sql #oracle #concatenation #delimiter #oracle18c

#sql #Oracle #конкатенация #разделитель #oracle18c

Вопрос:

У меня есть таблица, в которой есть нули:

STREET_NAME Расположение CULVER_TYPE CULVERT_WIDTH CULVERT_MATERIAL
MAIN ST ОТ ST A ДО ST B КАНАЛИЗАЦИОННЫЙ ЛИВЕНЬ ВОДОПРОПУСКНАЯ ТРУБА 1750 ТРУБА ИЗ ГОФРИРОВАННОЙ СТАЛИ
СТОРОНА ST ОТ ST C ДО ST D КАНАЛИЗАЦИОННЫЙ ЛИВЕНЬ ВОДОПРОПУСКНАЯ ТРУБА ТРУБА ИЗ ГОФРИРОВАННОЙ СТАЛИ
АРЕНА 1 КАНАЛИЗАЦИОННЫЙ ЛИВЕНЬ ВОДОПРОПУСКНАЯ ТРУБА 300
КАНАЛИЗАЦИОННЫЙ ЛИВЕНЬ ВОДОПРОПУСКНАЯ ТРУБА 500
.
 with cte as (
select 'MAIN ST' as STREET_NAME, 'FROM ST A TO ST B' as LOCATION, 'SEWER STORM  CULVERT' as CULVERT_TYPE,          1750 as CULVERT_WIDTH, 'CORRUGATED STEEL PIPE' as CULVERT_MATERIAL
from dual
union all
select 'SIDE ST' as STREET_NAME, 'FROM ST C TO ST D' as LOCATION,  'SEWER STORM  CULVERT' as CULVERT_TYPE,          null as CULVERT_WIDTH, 'CORRUGATED STEEL PIPE' as CULVERT_MATERIAL
from dual
union all
select null as STREET_NAME,      'ARENA 1' as LOCATION,            'SEWER STORM  CULVERT' as CULVERT_TYPE,          300 as CULVERT_WIDTH,  null as CULVERT_MATERIAL
from dual
union all
select null as STREET_NAME,      null as LOCATION,                 'SEWER STORM  CULVERT' as CULVERT_TYPE,          500 as CULVERT_WIDTH,  '' as CULVERT_MATERIAL
from dual
union all
select null as STREET_NAME,      null as LOCATION,                 null as CULVERT_TYPE,                              null as CULVERT_WIDTH, null as CULVERT_MATERIAL
from dual
)
select * from cte
 

Я хочу объединить значения в | столбец с разделителями по каналам (и игнорировать нули).

 CULVERT DESCRIPTION
----------------------
MAIN ST | FROM ST A TO ST B | SEWER STORM  CULVERT | 1750 | CORRUGATED STEEL PIPE
SIDE ST | FROM ST C TO ST D | SEWER STORM  CULVERT | CORRUGATED STEEL PIPE
ARENA 1 | SEWER STORM  CULVERT | 300
SEWER STORM  CULVERT | 500
<null>
 

Вопрос:

Есть ли способ выполнить динамическую конкатенацию, подобную этой, в Oracle 18c, игнорируя нули?

Было бы идеально, если бы решение представляло собой простую функцию, которая позволяла легко читать, например:

 dyamic_concat( delimiter , parameters [ column1 , column2, column3 ]... )
 

Ответ №1:

Используйте case .. when следующее:

 Select 
  Trim('|' from 
  case when street_name is not null then street_name end
  || case when location is not null then '|' || location end
  || case when culvert_type is not null then '|' || culvert_type end
  || case when culvert_width is not null then '|' || culvert_width end
  || case when culvert_material is not null then '|' || culvert_material end)
 From your_table;
 

Вы также можете использовать regexp_replace и trim следующим образом:

 Select 
 Trim('|' from 
      regexp_replace( street_name || '|' ||  location || '|' || 
      culvert_type || '|' || 
      culvert_width || '|' || culvert_material ,'[|] ','|'))
From your_table;
 

Комментарии:

1. Я обновил ответ со всеми столбцами и немного другой логикой.

2. Спасибо! Вопрос: Похоже regexp_replace , что опция усекает значения после обратной косой черты. Есть идеи, как это обойти? i.stack.imgur.com/PYmqG.png