0

I have a table with multiple string columns I would like to join together with a separator.

c1 c2 c3 c4
a b c d
a b
a

The result for that should be

'a-b-c-d'
'a-b'
'a'

In SQL Server I just do

select concat_ws('-', c1, c2, c3, c4) from my_table

In Oracle I can do

SELECT COALESCE(c1, '') || 
  CASE WHEN c2 IS NULL THEN '' ELSE '-' || c2 END || 
  CASE WHEN c3 IS NULL THEN '' ELSE '-' || c3 END ||
  CASE WHEN c4 IS NULL THEN '' ELSE '-' || c4 END  
FROM my_table

Is there a better solution in Oracle or even one that works for both - SQL Server and Oracle?

2
  • 2
    Does this answer your question? Is there an equivalent to concat_ws in oracle? Commented Sep 2, 2021 at 11:26
  • 1
    In terms of in both, unfortunately every dialect of SQL can be very different. For example even basic concatenation in T-SQL and PL/SQL is quite different, with them using + and || respectively. If you are working with multiple dialects, there are few times where you will have a query that is transferable without some kind of minimal change. Commented Sep 2, 2021 at 11:28

3 Answers 3

2

A version that works in both Oracle and SQL Server is tricky because the only string concatenation function available is concat() with two arguments. But, you can do:

select trim('-' from
        concat(coalesce(c1, ''),
              concat(case when c2 is null then '' else concat('-', c2) end,
                     concat(case when c3 is null then '' else concat('-', c3) end,
                            case when c4 is null then '' else concat('-', c4) end
                           )
                    )
             ))

Here are the two db<>fiddles for SQL Server and Oracle.

Sign up to request clarification or add additional context in comments.

Comments

1
select c1 || nvl2(c2, '-'||c2,c2) || nvl2(c3, '-'||c3,c3) || nvl2(c4, '-'||c4,c4)
from mytable

test it here

Comments

0

One option is to

  • concatenate all columns with - as a separator, and then
  • remove double (triple, ...) - signs (with regexp) and
  • remove leading/trailing - signs (with trim)

Something like this:

SQL> with test (c1, c2, c3, c4) as
  2    (select 'a' , 'b' , 'c' ,  'd' from dual union all
  3     select 'a' , 'b' , null, null from dual union all
  4     select 'a' , null, null, null from dual union all
  5     select 'a' , null, 'c' , null from dual union all
  6     select null, null, 'c' , 'd'  from dual
  7    )
  8  select
  9    c1, c2, c3, c4,
 10    --
 11    trim(both '-' from regexp_replace(c1 ||'-'|| c2 ||'-'|| c3 ||'-'|| c4, '-+', '-')) result
 12  from test;

C1 C2 C3 C4 RESULT
-- -- -- -- --------------------
a  b  c  d  a-b-c-d
a  b        a-b
a           a
a     c     a-c
      c  d  c-d

SQL>

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.