如何在SQL Server中连接字符串和逗号?

7

我对MSSQL比较新,如果问题听起来很琐碎,我很抱歉。我想用分隔符,连接多个字段。但是,当该字段为空时,额外的,也将包含在结果字符串中。所以有没有解决这个问题的简单方法呢?例如,

SELECT VRI.Street_Number_and_Modifier + ',' + 
       VRI.Street_Direction + ',' + 
       VRI.Street_Name + ',' + 
       VRI.Street_Direction + ',' + 
       VRI.Street_Suffix + ',' + 
       VRI.Street_Post_Direction + ',' + 
       VRI.Unit
FROM View_Report_Information_Tables VRI
13个回答

13

这是Lamak修改后的版本,可以处理NULL或仅包含空格/空字符的字符串:

SELECT  COALESCE(NULLIF(VRI.Street_Number_and_Modifier, '') + ',', '') + 
        COALESCE(NULLIF(VRI.Street_Direction, '') + ',', '') + 
        COALESCE(NULLIF(VRI.Street_Name, '') + ',', '') + 
        COALESCE(NULLIF(VRI.Street_Direction, '') + ',', '') + 
        COALESCE(NULLIF(VRI.Street_Suffix, '') + ',', '') + 
        COALESCE(NULLIF(VRI.Street_Post_Direction, '') + ',', '') + 
        COALESCE(NULLIF(VRI.Unit, ''), '')
FROM View_Report_Information_Tables VRI

不错 - 我不知道NULLIF。谢谢! - Joel Beckham
此示例无法运行。COALESCE函数需要至少2个参数。 - marisks

10

我能够用稍微不同的方法使其工作。将逗号放在每个字段的开头,然后使用STUFF函数删除第一个逗号对我有用:

SELECT 

    STUFF((COALESCE(', ' + NULLIF(VRI.Street_Number_and_Modifier, ''), '') +
        COALESCE(', ' + NULLIF(VRI.Street_Direction, ''), '') + 
        COALESCE(', ' + NULLIF(VRI.Street_Name, ''), '')) +
        COALESCE(', ' + NULLIF(VRI.Street_Direction, ''), '')) +
        COALESCE(', ' + NULLIF(VRI.Street_Suffix, ''), '')) +
        COALESCE(', ' + NULLIF(VRI.Street_Post_Direction, ''), '')) +
        COALESCE(', ' + NULLIF(VRI.Unit, ''), ''))
    , 1, 2, '')

FROM View_Report_Information_Tables AS VRI

括号有点混乱,但这个代码很有效! - Moo

6
如果列为空而不是null,你可以尝试这样做:

如果列为空而不是null,则可以尝试以下操作:

SELECT VRI.Street_Number_and_Modifier 
    + CASE WHEN VRI.Street_Number_and_Modifier <> '' THEN ', ' ELSE '' END
       + VRI.Street_Direction
    + CASE WHEN VRI.Street_Direction <> '' THEN ', ' ELSE '' END
       + VRI.Street_Name
    + CASE WHEN VRI.Street_Name <> '' THEN ', ' ELSE '' END
       + VRI.Street_Direction
    + CASE WHEN VRI.Street_Direction <> '' THEN ', ' ELSE '' END
       + VRI.Street_Suffix
    + CASE WHEN VRI.Street_Suffix <> '' THEN ', ' ELSE '' END
       + VRI.Street_Post_Direction
    + CASE WHEN VRI.Street_Post_Direction <> '' THEN ', ' ELSE '' END
       + VRI.Unit
    + CASE WHEN VRI.Unit<> '' THEN ', ' ELSE '' END
FROM View_Report_Information_Tables VRI

谢谢,但我现在遇到了语法错误:Incorrect syntax near '.' 有什么想法吗? - roxrook
@Chan - 正在研究可能是什么问题。此外,我还犯了一堆其他错误,我会尽快修复。 - Joel Beckham
现在,它完美地运行了。感谢如此优雅的解决方案 ;). - roxrook
1
@Chan - 请记住,这仅适用于字段为空字符串的情况。如果它们的值可能为null,则一定要考虑将其与其他解决方案结合使用。 - Joel Beckham

4

针对SQL 2008+

使用ISNULL(Colmn1 + ', ', '')将始终在末尾产生一个前导逗号,因此您需要处理它。 例如:

DECLARE @Column1 NVARCHAR(10) = 'Column1'
,   @Column2 NVARCHAR(10) = 'Column2'

SELECT  SUBSTRING(  ISNULL(@Column1 + ', ', '') + ISNULL(@Column2 + ', ', '')
            , 0 --Starting from 0 not 1 to remove leading comma
            , LEN(ISNULL(@Column1 + ', ', '') + ISNULL(@Column2 + ', ', '')))

或者我们可以采用另一种方法,使用STUFF函数来删除开头的逗号,这看起来更加清晰,例如:

SELECT  STUFF   (ISNULL(( ', ' + @Column1), '') + ISNULL(( ', ' + @Column2), ''), 1, 2, N'')

对于SQL 2012+,我们可以使用CONCAT函数,并使用STUFF类似于我们先前的示例来删除逗号开头,但避免使用ISNULL:

SELECT  STUFF(CONCAT( ', ' + @Column1, ', ' + @Column2), 1, 2, N'')
SQL 2017+引入了CONCAT_WS函数,可以使用函数的第一个参数指定分隔符来连接多个字符串列:

MS Documents CONCAT_WS

MS文档示例:

SELECT CONCAT_WS(',' --delimiter
            ,'1 Microsoft Way', NULL, NULL, 'Redmond', 'WA', 98052) AS Address;

2

试试这个:

SELECT  COALESCE(VRI.Street_Number_and_Modifier + ',','') + 
        COALESCE(VRI.Street_Direction + ',','') + 
        COALESCE(VRI.Street_Name + ',','') + 
        COALESCE(VRI.Street_Direction + ',','') + 
        COALESCE(VRI.Street_Suffix + ',','') + 
        COALESCE(VRI.Street_Post_Direction + ',','') + 
        COALESCE(VRI.Unit,'')
FROM View_Report_Information_Tables VRI

@Lamak:非常感谢,非常干净易懂。但是逗号还在那里:(。有什么想法吗? - roxrook
@Chan:你说的“逗号还在那里”是什么意思?能否展示一下输入和输出的例子?上面的查询应该能够正常工作,当一个字段为NULL时,就不应该有任何额外的逗号。 - Lamak
@Lamak:这是我得到的结果:,,Mae Rose,,Dr,, - roxrook
@Chan:我认为你的问题是当字段为空时,你并没有得到NULL,而是得到了一个空字符串''。 - Lamak
@Lamak:那我该如何处理这个问题呢?谢谢。 - roxrook
@Quandary: 我正在运行 SQL Server 2008 R. - roxrook

2

简短回答 - 不需要。这是一个格式问题,而不是数据库问题。

长篇回答 - 当你在sql server中连接一个字符串和一个null值时,结果就是null。因此,你可以使用ISNULL的组合。

SELECT ISNULL(afield + ',','') + ISNULL(bfield + ',','')

永远不会为空,因为您已将逗号添加到null。 - freegnu
1
@freegnu - SQL Server 2008及以后版本将Null和字符串拼接的结果视为Null。 - Jamiec
1
我尝试了这个方法在 MSSQL 2008 上,它按照我的要求工作。我想要连接 lastname + firstname + initial。在此之中,我只想在 lastname 不为空时插入逗号“,”。感谢 Jamlec 提供的信息。 - Code Buster

1

当IsNull(fieldname, '')= ''或ltrim(rtrim(fieldname))='')时,您必须使用select case。然后...否则...end +...

编辑:
是从Android手机编写的。
以下是您的示例。
以下翻译(来自德语),供参考:

Vorname: 名字
Name: 姓氏
Benutzer: 用户

这是示例代码:

CREATE VIEW [dbo].[V_RPT_SEL_Benutzer]  
AS  
SELECT 

    BE_ID AS RPT_UID, 

    CASE 
        WHEN (ISNULL(BE_Name, '0') = '0' OR LTRIM(RTRIM(BE_Name)) = '')  AND (ISNULL(BE_Vorname, '0') = '0' OR LTRIM(RTRIM(BE_Vorname)) = '')
            THEN ''
        WHEN (ISNULL(BE_Name, '0') = '0' OR LTRIM(RTRIM(BE_Name)) = '')
            THEN ISNULL(BE_Vorname, '') 
        WHEN (ISNULL(BE_Vorname, '0') = '0' OR LTRIM(RTRIM(BE_Vorname)) = '')
            THEN ISNULL(BE_Name, '') 
        ELSE
            ISNULL(BE_Name, '') + ', ' + ISNULL(BE_Vorname, '') 
    END AS RPT_Name, 

    ROW_NUMBER() OVER (ORDER BY BE_Name, BE_Vorname ASC) AS RPT_Sort 

FROM T_Benutzer  

你能给我一个例子吗?谢谢。 - roxrook
@Chan:添加了示例。@Cade Roux:这对于SQL 2008仍然有效吗?我记得需要它...好吧,ISNULL(BE_Name,'')= ''应该就足够了,所以忘记所有的or语句,但只有or,而不是and。 - Stefan Steiger

0
SELECT isnull(VRI.Street_Number_and_Modifier + ',','')+
   isnull(VRI.Street_Direction + ',','')+
   isnull(VRI.Street_Name + ',','')+
   isnull(VRI.Street_Direction + ',','')+
   isnull(VRI.Street_Suffix + ',','')+
   isnull(VRI.Street_Post_Direction + ',','')+
   isnull(VRI.Unit,'')
FROM View_Report_Information_Tables VRI

无法工作,因为当string2 = null时,逗号也需要被删除。 - Stefan Steiger
字段也可以是string.empty或者只有空格。此外,这仅适用于ms-sql 2008,其中string + null = null,不像sql 2005。 - Stefan Steiger
@Quandary 如果你的 ANSI_NULLs 是 ON 的话(即使在 SQL Server 2005 上默认也是 ON),在 SQL Server 2005 上,string + null = null。 - Cade Roux

0

如果是空字符串,这将不会添加任何逗号

SELECT CONCAT_WS(', ', IFNULL(column1, NULL), 
         IFNULL(column2, NULL), IFNULL(column3, NULL), 
         IFNULL(column4, NULL), IFNULL(column5, NULL))
FROM yourtable

Downvote,sqlserver 没有 CONCAT_WS 函数。那是 MYSQL 函数。 - coding Bott

0

我想看看是否可以不使用CASE语句来实现,但是没有成功。我自己的方法比较冗长:

    SELECT case when isnull(nullif(VRI.Street_Number_and_Modifier, ''),'')='' then '' else VRI.Street_Number_and_Modifier end
+ case when isnull(nullif(VRI.Street_Direction, ''),'')='' then '' else ',' + VRI.Street_Direction end
+ case when isnull(nullif(VRI.Street_Name, ''),'')='' then '' else ',' + VRI.Street_Name end
+ case when isnull(nullif(VRI.Street_Suffix, ''),'')='' then '' else ',' + VRI.Street_Suffix end
+ case when isnull(nullif(VRI.Street_Post_Direction, ''),'')='' then '' else ',' + VRI.Street_Post_Direction end
+ case when isnull(nullif(VRI.Street_Post_Direction, ''),'')='' then '' else ',' + VRI.Street_Post_Direction end
FROM View_Report_Information_Tables VRI

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接