【问题标题】:How to concatenate strings and commas in SQL Server?如何在 SQL Server 中连接字符串和逗号?
【发布时间】:2011-07-18 08:18:11
【问题描述】:

我对 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

【问题讨论】:

    标签: sql sql-server concatenation coalesce


    【解决方案1】:

    试试这个:

    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:非常感谢,非常简洁易懂。但是逗号仍然存在:(。有什么想法吗?
    • @Chan:你所说的“逗号还在”是什么意思?你能举个输入和输出的例子吗?上面的查询应该有效,当一个字段是NULL,你不应该得到任何额外的逗号。
    • @Lamak:这是我得到的结果:,,Mae Rose,,Dr,,
    • @Chan:我相信你的问题是当字段为空时你没有得到NULL,你得到的是一个''。
    • @Lamak:那么我该如何处理这个问题呢?谢谢。
    【解决方案2】:

    您可以使用ISNULL(field + ',', '')

    【讨论】:

    • 谢谢,不过逗号还在 :(。有什么想法吗?
    • 永远不会为空,因为您在 null 中添加了一个逗号。
    • @freegnu 试试这个 select isnull(null + ',','')。 Null + 'a string' 返回 null
    【解决方案3】:

    短答案还是长答案?

    简短的回答 - 不要。这是格式问题,不是数据库问题。

    长答案 - 当您在 sql server 中连接字符串和空值时,结果为空值。所以你可以使用 ISNULL 的组合

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

    【讨论】:

    • 永远不会为空,因为您在 null 中添加了一个逗号。
    • @freegnu - 2008 年的 SQL Server 调用 null + 字符串为 null。
    • 我在 MSSQL 2008 上试过这个,它按我的意愿工作。我想连接姓氏+名字+首字母。在此我想在姓氏不为空的情况下在姓氏之后插入一个逗号','。感谢 Jamlec 提供的信息
    【解决方案4】:
    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时逗号也需要去掉
    • 字段也可以是 string.empty 或只有空格。此外,这仅适用于 ms-sql 2008,其中 string + null =null,与 sql 2005 不同。
    • @Quandary string + null = null 在 SQL Server 2005 上,如果你有 ANSI_NULLs ON(默认情况下它应该是,即使在 SQL Server 2005 上)。
    【解决方案5】:

    当 IsNull(fieldname, '')= '' 或 ltrim(rtrim(fieldname))='') 时必须使用 select case Then ... Else... end +...

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

    Vorname:名字
    姓名:姓
    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  
    

    【讨论】:

    • 你能举个例子吗?谢谢。
    • @Chan:添加了示例。 @Cade Roux:SQL 2008 仍然如此吗?我记得需要它... 那么 ISNULL(BE_Name, '') = '' 就足够了,所以忘记所有 or 语句,但只有 or,而不是 and。
    【解决方案6】:

    我完全同意 Jamiec 的简短回答。

    否则,我会考虑在连接两列的任何地方使用 REPLACE([concat], ',,', ',') 的讨厌解决方案,然后弄清楚如何从开头和结尾修剪逗号第一列和最后一列可能为空的字符串。非常非常乱。

    【讨论】:

      【解决方案7】:

      如果列是空的而不是 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 '.' 有什么想法吗?
      • @Chan - 调查它可能是什么。此外,我还犯了许多其他错误,我会很快解决。
      • 现在,它运行良好。感谢您提供如此优雅的解决方案;)。
      • @Chan - 请记住,这仅在字段为空字符串时才有效。如果它们的值可能为空,您肯定会考虑将其与其他一些解决方案结合使用。
      【解决方案8】:

      此修改版的 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。谢谢!
      • 这个例子不起作用。 COALESCE 函数至少需要 2 个参数。
      【解决方案9】:

      我能够用一种稍微不同的方法让它工作。将逗号放在每个字段的开头,然后使用 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
      

      【讨论】:

      • 括号有点乱,但效果很好!
      【解决方案10】:

      想看看我是否可以在不使用 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
      

      【讨论】:

        【解决方案11】:
        SELECT  COALESCE(NULLIF(ad.UDEFPROPERTYADDRESS_ADDRSS_LN_1_TXT, ''), ',')+
            COALESCE(NULLIF(ad.UDEFPROPERTYADDRESS_ADDRSS_LN_2_TXT, '') , ',')+
            COALESCE(NULLIF(ad.UDEFPROPERTYADDRESS_ADDRSS_LN_3_TXT, '') , ',')+
            COALESCE(NULLIF(ad.UDEFPROPERTYADDRESS_CITY_TXT, '') , ',')+
            COALESCE(NULLIF(ad.UDEFPROPERTYADDRESS_ST_TXT, '') , ',')+
            COALESCE(NULLIF(ad.UDEFPROPERTYADDRESS_CNTRY_TXT, '') , ',')+
            COALESCE(NULLIF(ad.UDEFPROPERTYADDRESS_PSTL_CD, '') , '')
            FROM ACCOUNT_DETAILS ad
        

        【讨论】:

          【解决方案12】:

          如果为空字符串,则不会添加任何逗号

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

          【讨论】:

          • 投反对票,sqlserver 没有函数 CONCAT_WS。那是一个MYSQL函数。
          【解决方案13】:

          对于 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;
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2011-07-14
            • 1970-01-01
            • 2017-07-26
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多