Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CONCAT_WS() for SQL Server

How can I emulate MySQL's CONCAT_WS() function in SQL Server?

This function is similar to CONCAT() function in SQL Server 2012 except that it adds a separator between non-NULL items:

SELECT id, CONCAT_WS('; ', a, b, c, d) AS bar
FROM foo
ORDER BY id;
| ID | BAR        |
|----|------------|
|  1 | a; b; c; d |
|  2 | b; d       |
|  3 | a; d       |
|  4 |            |

(MySQL Fiddle)

like image 774
Álvaro González Avatar asked Oct 17 '13 16:10

Álvaro González


People also ask

What does Concat_ws do in SQL?

CONCAT_WS takes a variable number of string arguments and concatenates (or joins) them into a single string. It separates those concatenated string values with the delimiter specified in the first function argument.

What is the difference between concat and Concat_ws in SQL?

Both CONCAT() and CONCAT_WS() functions are used to concatenate two or more strings but the basic difference between them is that CONCAT_WS() function can do the concatenation along with a separator between strings, whereas in CONCAT() function there is no concept of the separator.

How do I concatenate 3 columns in SQL?

To concatenate more than 2 fields with SQL, you can use CONCAT() or CONCAT_WS() function.

What does Concat_ws stand for?

CONCAT_WS stands for concatenation with separator. The first argument is a separator that is placed in between the remaining arguments when concatenating them together. If any of the expressions is NULL it is skipped in the concatenated output.

How do I concatenate two rows in SQL Server?

Concatenate Rows Using COALESCE All you have to do is, declare a varchar variable and inside the coalesce, concat the variable with comma and the column, then assign the COALESCE to the variable.


1 Answers

We can use a couple of tricks:

  • To skip NULL values: COALESCE()
  • To avoid trailing separator: add it before every item, remove the first one afterwards with e.g. STUFF()

He's a working example:

CREATE TABLE foo (
  id INT IDENTITY(1, 1) NOT NULL,
  a VARCHAR(50),
  b VARCHAR(50),
  c VARCHAR(50),
  d VARCHAR(50),
  PRIMARY KEY (id)
);

INSERT INTO foo (a, b, c, d) VALUES ('a', 'b', 'c', 'd');
INSERT INTO foo (a, b, c, d) VALUES (NULL, 'b', NULL, 'd');
INSERT INTO foo (a, b, c, d) VALUES ('a', NULL, NULL, 'd');
INSERT INTO foo (a, b, c, d) VALUES (NULL, NULL, NULL, NULL);
SELECT id,
STUFF(
    COALESCE('; ' + a, '') +
    COALESCE('; ' + b, '') +
    COALESCE('; ' + c, '') +
    COALESCE('; ' + d, ''),
1, 2, '') AS bar
FROM foo
ORDER BY id
| ID | BAR        |
|----|------------|
|  1 | a; b; c; d |
|  2 | b; d       |
|  3 | a; d       |
|  4 | (null)     |

The purpose of STUFF(..., 1, 2, '') is to remove the initial separator (2 is the separator length in our case).

This should work on SQL Server 2005 (and possibly earlier versions).

Note: unlike the original CONCAT_WS(), our version returns NULL when all items are NULL. I honestly think it's a better choice but it should be easy to change anyway.

like image 100
Álvaro González Avatar answered Oct 09 '22 01:10

Álvaro González