在 T-SQL 中实现“ANY”聚合运算符

Mih*_*hai 2 sql-server

我有一个包含部门和员工表的数据库,我需要返回每个部门的员工人数。我写了以下查询:

SELECT d.ID, d.Name, COUNT(*) EmployeeCount
  FROM dbo.Departments d
       INNER JOIN dbo.Personnel p 
       ON p.DepartmentID = d.ID
GROUP BY d.ID, d.Name;
Run Code Online (Sandbox Code Playgroud)

问题是,我担心GROUP BY操作员在处理VARCHAR色谱柱时会变慢。我希望能够写

SELECT d.ID, ANY(d.Name), COUNT(*)  EmployeeCount
  FROM dbo.Departments d
       INNER JOIN dbo.Personnel p 
       ON p.DepartmentID = d.ID
GROUP BY d.ID;
Run Code Online (Sandbox Code Playgroud)

我可能会使用 MIN/MAX 聚合函数,但它们可能会使查询更慢。我知道,在 MySQL 中,您可以选择未出现在GROUP BY子句中的列,DB 引擎将随机返回该列的任何行值。在 T-SQL 中这样的事情可行吗?

Aar*_*and 8

我认为您正在尝试优化不存在的性能问题。我不知道为什么你认为 aGROUP BY在这里会有问题。从概念上讲,您编写的内容与以下内容之间没有太大区别:

SELECT d.Id, d.Name, s.c
  FROM dbo.Departments AS d
  INNER JOIN 
  (
    SELECT ID = DepartmentID, c = COUNT(*)
    FROM dbo.Personnel 
    GROUP BY DepartmentID
  ) AS s
  ON d.ID = s.ID;
Run Code Online (Sandbox Code Playgroud)

因此,这个查询没有做GROUP BY的姓名列,但在我的测试其实这是,除非你创建一个非聚集索引比你的版本有效Personnel.DepartmentID(在这种情况下,计划是完全一样的)。我建议在您实际观察到性能问题时优化性能,而不是基于预感。在您的情况下,分组基本上是免费的,因为它是同一个聚集索引扫描的一部分,无论如何都必须读取所有数据。我不确定如何强制 SQL Server 选择一个随机名称(无论如何,该名称将与您已经阅读的 ID 位于同一行)可能会使任何事情变得更快......