在 GROUP BY 之后连接一个字段

Posted

技术标签:

【中文标题】在 GROUP BY 之后连接一个字段【英文标题】:Concatenate one field after GROUP BY 【发布时间】:2012-11-18 19:15:17 【问题描述】:

这个问题在 SO 中被问过很多次,但没有一个答案能满足我的情况。

    Question 1 Question 2 Question 3 Question 4

我正在处理一个 DataObjectVersions 表,其中包含大约 120 万个唯一对象(并且还在增加)的多个版本。我需要为每个唯一对象连接来自特定字段的更改。

现在我正在使用第三季度中提供的 XML 路径的解决方案,但是在这个表上运行这样的查询是一个完全的性能灾难。 SQL Server 在 1900 万之后开始返回数据。知道这个数据会比 join 两次,你可以想象它的影响。

我正在寻找一种最有效的可扩展性感知方式来连接由另一个字段(当然不是键)分组的不同行的相同字段的值。更准确地说,这是在数据仓库的视图中使用的。

编辑:

我试图简化描述,但这里有一个完整的概述 我有多个包含以下列的表格

[ID] [创建时间] [由...制作] [删除时间] [删除者] [资源 ID] [帐户ID] [类型]

视图用于返回所有表中所有记录的联合,该联合仍将返回相同的列(在我的问题中由版本表描述)。 [ResourceId][AccountId] 是对象的唯一复合标识符(组成员身份、系统帐户等。特别是资源分配)。 [Type] 用于标识不同的级别(如文件分配情况下的读/写/执行)

对于不同的唯一对象,所有其他字段都包含相同的值(在不同的表中)。我需要获取对象并连接[Type] 列的值。之后处理所有行,并且 ([ResourceId],[AccountId]) 组合必须是唯一的(存在不同类型时不是这种情况)。

编辑 2:

我正在使用这个功能:

CREATE FUNCTION [dbo].[GetUniqueType]
(
    @ResourceId as uniqueidentifier,
    @Account as uniqueidentifier
)
RETURNS nvarchar(100)
AS
BEGIN   
    return STUFF((select ',' + raType.Type from vwAllAssignments raType where raType.AccountId = @Account and raType.ResourceId = @ResourceId and raType.DeletedBy is null for xml path('')), 1,1,'')
END

GO

vwAllAssignments 是返回所有表行的并集的视图。

我终于选择了

SELECT [CreatedTime]
      ,[DeletedTime]
      ,[DeletedBy]
      ,[ResourceId]
      ,[AccountId]
      ,dbo.GetUniqueType([ResourceId],[AccountId]) AS [Type]
FROM vwAllAssignments
GROUP BY [ResourceId], [AccountId], [CreatedTime], [DeletedTime], [DeletedBy]

【问题讨论】:

你的意思是像“Object”、“V1、V2、V3、V4”这样的东西吗? 是的,但仅针对特定列,并非所有列都像连接类型或从不同版本更改日期 请显示您的数据库布局。我在更大的表上使用 SQL Server 8 中的连接并获得更好的性能。我怀疑一些放置得当的索引会解决性能问题。 请发布您现有的代码。 你能用你的 vwAllAssignments 视图的一些行设置一个 sqlfiddle 吗? 【参考方案1】:

试试这个:

SELECT [CreatedTime]
      ,[DeletedTime]
      ,[DeletedBy]
      ,[ResourceId]
      ,[AccountId]
      ,STUFF((select ',' + raType.Type 
              from vwAllAssignments raType 
              where raType.AccountId = vwAllAssignments.AccountId and 
                    raType.ResourceId = vwAllAssignments.ResourceId and 
                    raType.DeletedBy is null 
              for xml path('')), 1,1,'') AS [Type]
FROM vwAllAssignments
GROUP BY [ResourceId], [AccountId], [CreatedTime], [DeletedTime], [DeletedBy]

这样的索引应该会有所帮助。

create index IX_vwAllAssignments on vwAllAssignments(AccountId, ResourceId, DeletedBy) include(Type)

【讨论】:

以上是关于在 GROUP BY 之后连接一个字段的主要内容,如果未能解决你的问题,请参考以下文章

SQL group by 连接查询结果的字符串

MySQL调优--05---多表查询优化子查询优化 ORDER BY优化GROUP BY优化分页查询优化

用group by语句时,字段很多并且数据量也很大的情况如何解决?

MYsql5.7版本之后,用group by查询不在分组字段遇到的坑

sql中order by和group by的区别

如何在连接多个表时使用 GROUP BY 连接字符串?