使用分隔符连接或合并许多列值并忽略空值 - SQL Server 2016 或更早版本

Concatenate or merge many columns values with a separator between and ignoring nulls - SQL Server 2016 or older

我想用 SQL Server 2016 或更早版本模拟 CONCAT_WS SQL Server 2017+ 函数,以便连接许多值是字符串的列:

输入:

| COLUMN1 | COLUMN2 | COLUMN3 | COLUMN4 |
   'A'        'B'       NULL     'D'
   NULL       'E'       'F'      'G'
   NULL       NULL      NULL     NULL

输出:

| MERGE |
 'A|B|D'
 'E|F|G'
  NULL

请注意,输出结果是一个新列,它连接了用“|”分隔的所有值。如果列中没有值,则默认值应为 NULL。

我尝试使用 CONCAT 和带有许多 WHEN 条件的 CASE 语句,但确实很脏,我不允许使用此解决方案。提前致谢。

一种方便的方法是:

select stuff( coalesce(',' + column1, '') +
              coalesce(',' + column2, '') +
              coalesce(',' + column3, '') +
              coalesce(',' + column4, ''), 1, 1, ''
            )

         

这是使用 XML 和 XQuery 的另一种方法。

列数不是硬编码的,它可以是动态的。

SQL

-- DDL and sample data population, start
DECLARE @tbl TABLE (id INT IDENTITY PRIMARY KEY, col1 CHAR(1), col2 CHAR(1), col3 CHAR(1), col4 CHAR(1));
INSERT INTO @tbl (col1, col2, col3, col4) VALUES
( 'A',  'B',  NULL, 'D'),
(NULL, 'E' , 'F'  , 'G'),
(NULL, NULL, NULL , NULL);
-- DDL and sample data population, end

DECLARE @separator CHAR(1) = '|';

SELECT id, REPLACE((
    SELECT * 
    FROM @tbl AS c
    WHERE c.id = p.id
    FOR XML PATH('r'), TYPE, ROOT('root')
).query('data(/root/r/*[local-name() ne "id"])').value('.', 'VARCHAR(100)') , SPACE(1), @separator) AS concatColumns
FROM @tbl AS p;

输出

+----+---------------+
| id | concatColumns |
+----+---------------+
|  1 | A|B|D         |
|  2 | E|F|G         |
|  3 |               |
+----+---------------+