【问题标题】:How can I pull a list of ID's from a SQL table as a comma-separated values string?如何从 SQL 表中提取 ID 列表作为逗号分隔值字符串?
【发布时间】:2011-01-07 12:33:46
【问题描述】:

我必须仅使用符合某些条件的记录从表中提取整数 ID 列表。例如:

Select ProdID From Products Where (ProdType='XYZ');

问题是我必须将它作为一组逗号分隔值返回,以便我可以使用它来选择多选列表中的项目:

111,231,554,112

而不是作为记录。我不想在我的 C# 代码中执行此操作 - 我希望它通过这种方式通过查询直接从数据库中出来。有什么想法吗?

【问题讨论】:

  • 糟糕,很好的答案。赞成票。我不知道该怎么做。很酷。

标签: sql sql-server sql-server-2008


【解决方案1】:

MySQL


SELECT GROUP_CONCAT(t.prodid SEPARATOR ',')
  FROM PRODUCTS t
 WHERE t.prodtype = 'XYZ'

甲骨文:


Tim Hall 的网站上有对available string aggregation techniques 的精彩总结。

SQL Server 2005+


SELECT STUFF((SELECT ','+ t.prodid
                FROM PRODUCTS t
               WHERE t.prodtype = 'XYZ'
             FOR XML PATH('')), 1, 1, '')

【讨论】:

  • @OMG Ponies - 对于 SQLServer 案例,您知道是否有使用 coalese 的方法: select @ids = coalesce(@ids + ',', '') + convert(varchar, id) from ids会比你的方法慢很多吗?
  • 回答我自己的问题,Rob Farley 有一个帖子解决了这个问题msmvps.com/blogs/robfarley/archive/2007/04/08/…
  • @David Hall:使用COALESCE 要求您首先声明变量-STUFF 不需要。如果可以的话,明天会比较性能。
  • +1 - 我应该提到这是 SQL Server 2008 - 抱歉!
  • 小马 - 我想看看这个比较!我给了 Justin 答案,因为它是 Coalesce 的第一个答案,我在存储过程中执行此操作。不过,我很想看看你的分析结果。
【解决方案2】:

除了@OMG Ponies 方法,您还可以尝试以下 COALESCE 技巧:

Using COALESCE to Build Comma-Delimited Strings

declare @string nvarchar(255)

select @string = coalesce(@string + ', ', '') + cast(prodid as nvarchar(5))
from products

【讨论】:

  • @OMG Ponies - 感谢您的阅读。很高兴知道有一种更可靠的方法来构建刺痛。
  • 整洁。我只需要在另一个方向上执行此操作,有人认为在数据库中存储逗号分隔值列表是个好主意。我想知道在 SQL 中执行此操作是否比客户端上的数组操作有什么特别的好处?
  • 我正在使用 sql server ,并且 工作 仅在末尾添加此语句时:select @string as CommaSeparated
【解决方案3】:

从 SQL Server 2017 开始,您现在可以使用 STRING_AGG 函数。

这允许您从 SELECT 语句中创建逗号分隔的列表(因此可以很好地与视图一起使用)。鉴于您的示例,它将变为:

SELECT STRING_AGG(ProdID, ',') FROM Products WHERE (ProdType='XYZ');

【讨论】:

    【解决方案4】:

    对于 SQL 服务器,请参见此处:Concatenate Values From Multiple Rows Into One Column

    【讨论】:

      【解决方案5】:

      这是一个非常古老的问题,但我添加了一个答案,该答案应用了 Justin Niessner 使用 COALESCE 已经接受的答案。此应用程序是我通常希望在查询父级时应用此技术的方式,并且我还希望有一个包含逗号分隔的子 ID 列表的列。

      如果您在预配数据库时使用下拉列表将其选中,则这些示例与在 Azure SQL 数据库中创建的 AdventureWorksLT 数据库背道而驰。这里没有什么新东西,只是一个可能对某人有所帮助的便捷应用程序。

      第一个查询是我通常如何使用它:

      SELECT
          SalesLT.ProductCategory.*,
          STUFF((SELECT ','+ cast(ProductID as nvarchar(10)) FROM SalesLT.Product WHERE ProductCategoryID=SalesLT.ProductCategory.ProductCategoryID ORDER BY ProductID FOR XML PATH('')), 1, 1, '') AS ProductIDs
      FROM SalesLT.ProductCategory
      

      第二个查询显示了它的自引用用法:

      SELECT
          ParentCategory.*,
          STUFF((SELECT ','+ cast(child.ProductCategoryID as nvarchar(10)) FROM SalesLT.ProductCategory child WHERE child.ParentProductCategoryID=ParentCategory.ProductCategoryID ORDER BY child.ProductCategoryID FOR XML PATH('')), 1, 1, '') AS ChildCategoryIDs
      FROM SalesLT.ProductCategory ParentCategory
      WHERE
          EXISTS (SELECT ParentProductCategoryID FROM SalesLT.ProductCategory children WHERE children.ParentProductCategoryID=ParentCategory.ProductCategoryID)
      

      【讨论】:

        【解决方案6】:

        有一种方法可以在没有附加功能的情况下做到这一点:

        DECLARE @Test nvarchar(max) = ''
        
        SELECT @Test = @Test + ProdID + ', '
        FROM Products 
        WHERE (ProdType='XYZ')
        
        SELECT @Test
        

        @Test 将包含您的 ID 列表,尽管我无法解释为什么会这样。

        【讨论】:

        • 我尝试了这个没有函数的版本,但遇到了两个问题:1. 因为我的 ProdID 是 Int,所以我必须向它添加强制转换 2. 我总是在末尾有一个尾随 ',' @Test 需要删除的
        猜你喜欢
        • 1970-01-01
        • 2011-05-26
        • 1970-01-01
        • 2013-08-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-19
        • 1970-01-01
        相关资源
        最近更新 更多