【问题标题】:SQL - Combine Multiple Rows of Data to One Row and ColumnSQL - 将多行数据合并为一行和一列
【发布时间】:2015-06-10 00:34:46
【问题描述】:

我希望创建一个 SQL Server 查询,该查询将使用三个表将具有相同任务的资源组合成一个行/记录字符串。下面的我的 SQL Server 查询似乎无法正常工作,需要很长时间才能执行,然后出错。谢谢!

任务表

TaskUID
TaskName

作业表

TaskUID
ResourceUID

资源表

ResourceUID
ResourceName

之前

**Task Name     Resource Name**
Weapon Launch   Amy
Weapon Launch   Sam
Weapon Launch   Marisa
Weapon Launch   Katy
Weapon Launch   John
Sweating Tears  Marisa
Sweating Tears  Joe
Sweating Tears  Katy
Sweating Tears  Michael
Ramp Diver      Joe
Ramp Diver      Michael

之后

**Task Name     Resource Name**
Weapon Launch   Amy; Sam; Marisa; Katy; John
Sweating Tears  Marisa; Joe; Katy; Michael
Ramp Diver      Michael; Joe

查询

SELECT T.TaskName,
STUFF(( SELECT ', ' + R.RESOURCENAME
FROM 
[Resource Table] R
LEFT JOIN [Assignment Table] A ON R.ResourceUID=A.ResourceUID
WHERE
A.TASKUID=T.TaskUID
Group by R.RESOURCENAME
FOR XML PATH('')), 1, 1,'') Resources
FROM [Task Table] T
INNER JOIN [Assignment Table] A ON T.TASKUID=A.TASKUID

【问题讨论】:

  • 带回三个结果集并自己将它们压缩在一起。这是最简单的方法。
  • 查看this SO post了解如何执行此操作。
  • 您可以使用程序集创建聚合函数。
  • 您的表中有索引吗?它有很大的不同。我相信 ID 是 Resource 和 Task 表的索引。 [分配表]呢? (sqlfiddle.com/#!3/4efb8/1)
  • 不,我们在表中没有索引。

标签: sql-server for-xml-path


【解决方案1】:

请尝试:

SELECT T.TaskName, Resources
FROM TaskTable T
CROSS APPLY (
  SELECT 
    STUFF(( SELECT ', ' + R.RESOURCENAME
      FROM [ResourceTable] R
      INNER JOIN [AssignmentTable] A ON R.ResourceUID=A.ResourceUID
      WHERE A.TASKUID = T.TASKUID
      Group by R.RESOURCENAME
      FOR XML PATH('')), 1, 1,'') Resources
) N(Resources)

SQL Fiddle

【讨论】:

  • Nizam,我试过了,执行时间超过 15 分钟。我的 [TaskTable] 有大约 40,000 条记录。我认为它最终会完成,但运行起来需要相当长的时间。感谢您的帮助!
  • 你的资源表呢?
  • [ResourceTable] 中大约有 900 条记录。
  • 我以前从未做过程序集,而且我对 SQL Server 还是很陌生。也不确定是否需要特殊权限才能在我的环境中进行组装。
  • 看看我上面的评论。创建聚合函数非常容易。我已经打包了一个 DLL 来执行此操作。我觉得值得一试。
【解决方案2】:

感谢 Nizam,我发现我应该使用数据库中的表而不是视图,因为我没有创建索引的权限。内置索引允许更快的查询。

SELECT DISTINCT
T.TASK_NAME,
    STUFF((SELECT ', '+ R.RES_NAME
            FROM PUB.MSP_RESOURCES R
            JOIN PUB.MSP_ASSIGNMENTS A ON A.RES_UID=R.RES_UID
            WHERE A.TASK_UID=T.TASK_UID
            AND R.RES_TYPE IN(2)
            GROUP BY R.RES_NAME
            FOR XML PATH(''), TYPE).value('.','VARCHAR(max)'), 1, 1, '') AS RESOURCES

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-09
    • 1970-01-01
    • 2018-06-13
    • 2012-05-27
    • 1970-01-01
    • 2016-04-27
    • 1970-01-01
    相关资源
    最近更新 更多