【问题标题】:Is COALESCE the best way to achieve this?COALESCE 是实现这一目标的最佳方式吗?
【发布时间】:2010-01-13 09:16:41
【问题描述】:

只是想看看是否有人有更好的方法来完成我所需要的。

首先是背景。我的数据库中有一个表,目前有大约 20,000 行。在表中,我们有一列用于 FirstName 和 LastName。还有一列是 ReferenceID。每个 ReferenceID 可以有多个 FirstName、LastName 组合。

这意味着当我们从表中选择 * 时,我们会为每个 ReferenceID 返回多行(因为每个用户都有一行)。

我想将这两列连接到一个名为 Name 的列中,同时将每一行作为 ReferenceID 并将其变成一个。 (基本上是扁平化数据)。

让我试着在这里画一个ascii图。

TABLE
ID        ReferenceID        FirstName        LastName
________________________________________________
1         1                  Mike             Ekim
2         1                  Tom              Mot
3         1                  Pete             Etep
4         2                  Ryan             Nayr
5         3                  Jerry            Yrrej

所以我想要的最终结果是一个集合,例如

RESULT SET
ReferenceID   Name
__________________________________
1              Mike Ekim, Tom Mot, Pete Etep
2              Ryan Nayr
3              Jerry Yrrej

我真正需要知道的是,在我开始使用 COALESCE 并尝试调整我的结果之前,有没有更好的方法来实现这一点?使用 SQL Server 2005。

干杯,

迈克

【问题讨论】:

    标签: sql sql-server-2005


    【解决方案1】:

    以下是使用 xml 路径技术的方法(其中也有合并...)

    SELECT DISTINCT n.ReferenceID,
    STUFF((SELECT ', ' + COALESCE(n2.FirstName+' '+n2.LastName,n2.FirstName,n2.LastName,'NoName') 
        FROM namelist n2
        WHERE n.referenceid = n2.referenceid
        ORDER BY n2.lastname, n2.firstname
        FOR XML PATH('')
      ), 1, 2, '') AS [Name]
    FROM namelist n
    

    【讨论】:

    • 看起来不错霍根..我明天上班时会尝试..累到启动VPN:P
    • 是的,但我的要求发生了变化,毕竟我不需要它:P
    • 您能否解释一下这个查询,我不明白“For XML Path”在做什么。非常感谢任何/所有帮助。
    • @HappyDev - 我可以尝试,但 Mirosoft 做得更好。 FOR XML 转换为 XML (msdn.microsoft.com/en-us/library/ms189885.aspx)。 PATH('') 删除格式(参见 msdn.microsoft.com/en-us/library/bb510462.aspx 部分使用 PATH 模式生成值列表)
    【解决方案2】:

    您可以使用FOR XML PATH 生成逗号分隔的列表。例如见blog post:

    SELECT P.Name + ','
    FROM Production.Product AS P
    ORDER BY P.Name
    FOR XML PATH('')
    

    【讨论】:

      【解决方案3】:

      这篇文章涵盖了这个主题:Concatenating Row Values in Transact-SQL。有几种技术(XML PATH、递归 CTE、CLR、递归 UDF、基于游标、变量连接),每一种都简要介绍,并且文章中的 cmets 和链接资源进一步涵盖了该主题。

      我最喜欢的技术是 XML PATH(正如 Andomar 已经发布的那样)。

      【讨论】:

        【解决方案4】:

        我觉得不错。过去,我做过类似的事情,发现COALESCE 技巧是最直接的方法。

        这是一个经常需要的功能,除非您知道自己在寻找什么,否则很难找到它,所以这里有一篇很好的文章详细描述了如何做到这一点:http://www.sqlteam.com/article/using-coalesce-to-build-comma-delimited-string

        【讨论】:

        • 这真的很接近我的想法。对我来说困难的部分(可能是脑子放屁)是我有成千上万的身份证。这意味着对于每个 ID,我认为我们必须重新开始合并。除非我们不用游标就能做到?
        • codeSeth 的链接向您展示了如何在没有光标的情况下执行此操作,但这是一个简单的示例:DECLARE @csv VARCHAR(100); WITH Person AS ( SELECT 'bob' name UNION SELECT 'joe' UNION SELECT 'jim' ) SELECT @csv=COALESCE(@csv + ', ', '') + name FROM Person;打印@csv
        【解决方案5】:

        另一个选择是使用 CLR。您可以创建一个用 c# 或 VB.Net 编写的自定义用户定义聚合,该聚合将返回一个逗号分隔的列表(然后可以像使用 SUM 一样完全使用该列表,或者COUNT)。

        请参阅 this pagethis page 以开始使用。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-12-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-11-08
          • 1970-01-01
          • 1970-01-01
          • 2011-11-23
          相关资源
          最近更新 更多