You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL Server如何仅拼接非空列?CASE WHEN实现效果不佳

问题

在SQL Server中,有没有办法只拼接非空的列?我试过用CASE WHEN实现,但过程太繁琐,不想在字段为空或NULL时,把包含“名称+字段+', '”的整段内容都拼进去。比如:

'Sub-título: ', p.[config_metadata subtitle],', ',

这段对应的字段不为空时就保留,但如果是:

'Descrição: ', p.[last_timeline descricao],', ', 

对应的字段为NULL,就完全不拼接这段内容。

期望输出示例:如果第一、第三段对应的字段非空,第二段为空,结果应该是:

'Sub-título: field content, Fwd_descrição: field content, '

我当前用CONCAT函数的SQL语句如下:

SELECT 
    p._id AS id_documento,
    '16' AS id_fluxo,
    p.nP AS np,
    t.evento,
    YEAR(created_at) AS ano_doc,
    p.[config_metadata title] AS assunto, 
    CONCAT ('Sub-título: ', p.[config_metadata subtitle],', ',
        'Descrição: ', p.[last_timeline descricao],', ',
        'Fwd_descrição: ', p.[last_timeline forwardingDescription],', ',
        'Justificativa: ', p.[last_version Justificativa],', ',
        'Motivo: ', p.[last_version motivo],', ',
        'Área propriedade: ', p.[last_version areapropriedade],', ',
        'Endereço: ', p.[last_version endereco],', ',
        'Atividade: ', p.[last_version atividade],', ',
        'Atividade empreendida: ', p.[last_version atividadeempreend],', ',
        'Descreva finalidade: ', p.[last_version descrevafinalidade],', ',
        'Nome: ', p.[last_version nome],', ',
        'Nome empreendimento: ', [last_version nomeempreendimento],', ',
        'Quantidade: ', [last_version quantidade],', ',
        'Outros: ', [last_version outros],', ',
        'Data finalizado: ', p.[finalizado date] ) AS conteudo,
    '' as codigo,
    '0' as prioridade,
    t.from_id,
    t.from_nome,
    t.to_id,        
    t.to_nome,
    CONVERT(DATE,[created_at]) AS dia,
    CONVERT(TIME(0), [created_at]) AS hora,
    created_at
FROM 
    my_table AS p
JOIN 
    my_table2 AS t ON p._id = t.pid
WHERE 
    t.evento = 'Processo criado' 

使用的SQL Server版本:

Microsoft SQL Server 2022 (RTM-GDR) (KB5021522) - 16.0.1050.5 (X64)   
Jan 23 2023 17:02:42   
Copyright (C) 2022 Microsoft Corporation  
Developer Edition (64-bit) on Windows 10 Home Single Language 10.0 <X64> (Build 22621: ) (Hypervisor) 
解决方案

针对SQL Server 2022,有两种简洁的方法可以实现只拼接非空字段的需求:

方法1:使用CONCAT_WS + NULLIF

利用CONCAT_WS自动忽略NULL值的特性,结合NULLIF把空字符串转为NULL,就能跳过空字段的拼接:

SELECT 
    p._id AS id_documento,
    '16' AS id_fluxo,
    p.nP AS np,
    t.evento,
    YEAR(created_at) AS ano_doc,
    p.[config_metadata title] AS assunto, 
    CONCAT_WS(', ',
        NULLIF('Sub-título: ' + p.[config_metadata subtitle], 'Sub-título: '),
        NULLIF('Descrição: ' + p.[last_timeline descricao], 'Descrição: '),
        NULLIF('Fwd_descrição: ' + p.[last_timeline forwardingDescription], 'Fwd_descrição: '),
        NULLIF('Justificativa: ' + p.[last_version Justificativa], 'Justificativa: '),
        NULLIF('Motivo: ' + p.[last_version motivo], 'Motivo: '),
        NULLIF('Área propriedade: ' + p.[last_version areapropriedade], 'Área propriedade: '),
        NULLIF('Endereço: ' + p.[last_version endereco], 'Endereço: '),
        NULLIF('Atividade: ' + p.[last_version atividade], 'Atividade: '),
        NULLIF('Atividade empreendida: ' + p.[last_version atividadeempreend], 'Atividade empreendida: '),
        NULLIF('Descreva finalidade: ' + p.[last_version descrevafinalidade], 'Descreva finalidade: '),
        NULLIF('Nome: ' + p.[last_version nome], 'Nome: '),
        NULLIF('Nome empreendimento: ' + [last_version nomeempreendimento], 'Nome empreendimento: '),
        NULLIF('Quantidade: ' + [last_version quantidade], 'Quantidade: '),
        NULLIF('Outros: ' + [last_version outros], 'Outros: '),
        NULLIF('Data finalizado: ' + CONVERT(VARCHAR, p.[finalizado date]), 'Data finalizado: ')
    ) AS conteudo,
    '' as codigo,
    '0' as prioridade,
    t.from_id,
    t.from_nome,
    t.to_id,        
    t.to_nome,
    CONVERT(DATE,[created_at]) AS dia,
    CONVERT(TIME(0), [created_at]) AS hora,
    created_at
FROM 
    my_table AS p
JOIN 
    my_table2 AS t ON p._id = t.pid
WHERE 
    t.evento = 'Processo criado' 

逻辑说明:

  • 当字段为空时,'名称: ' + 空字段的结果就是'名称: ',此时NULLIF会返回NULL
  • CONCAT_WS会自动忽略所有NULL参数,只拼接非NULL的部分,并用指定的, 作为分隔符

方法2:使用STRING_AGG + VALUES子句

这种方法更灵活,把每个字段和对应的标签组成临时行,过滤空值后再聚合拼接:

SELECT 
    p._id AS id_documento,
    '16' AS id_fluxo,
    p.nP AS np,
    t.evento,
    YEAR(created_at) AS ano_doc,
    p.[config_metadata title] AS assunto, 
    (
        SELECT STRING_AGG(CAST(item AS VARCHAR(MAX)), ', ')
        FROM (VALUES
            ('Sub-título: ' + p.[config_metadata subtitle]),
            ('Descrição: ' + p.[last_timeline descricao]),
            ('Fwd_descrição: ' + p.[last_timeline forwardingDescription]),
            ('Justificativa: ' + p.[last_version Justificativa]),
            ('Motivo: ' + p.[last_version motivo]),
            ('Área propriedade: ' + p.[last_version areapropriedade]),
            ('Endereço: ' + p.[last_version endereco]),
            ('Atividade: ' + p.[last_version atividade]),
            ('Atividade empreendida: ' + p.[last_version atividadeempreend]),
            ('Descreva finalidade: ' + p.[last_version descrevafinalidade]),
            ('Nome: ' + p.[last_version nome]),
            ('Nome empreendimento: ' + [last_version nomeempreendimento]),
            ('Quantidade: ' + [last_version quantidade]),
            ('Outros: ' + [last_version outros]),
            ('Data finalizado: ' + CONVERT(VARCHAR, p.[finalizado date]))
        ) AS temp(item)
        WHERE item IS NOT NULL AND NOT item LIKE '%: '
    ) AS conteudo,
    '' as codigo,
    '0' as prioridade,
    t.from_id,
    t.from_nome,
    t.to_id,        
    t.to_nome,
    CONVERT(DATE,[created_at]) AS dia,
    CONVERT(TIME(0), [created_at]) AS hora,
    created_at
FROM 
    my_table AS p
JOIN 
    my_table2 AS t ON p._id = t.pid
WHERE 
    t.evento = 'Processo criado' 

逻辑说明:

  • VALUES子句把每个标签+字段的组合转为临时行数据
  • WHERE子句过滤掉NULL值,以及仅含标签的无效内容(用NOT item LIKE '%: '统一匹配所有空标签)
  • STRING_AGG把剩下的有效内容用, 拼接成最终字符串

两种方法都能替代繁琐的CASE WHEN写法,其中方法1更简洁,更适配你的场景。


内容的提问来源于stack exchange,提问作者Vinícius Sodré Quadros

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 12:57:25