如何在 NorthWind SQL Server 上执行聚合?

Posted

技术标签:

【中文标题】如何在 NorthWind SQL Server 上执行聚合?【英文标题】:How to perform aggregatin on NorthWind SQL Server? 【发布时间】:2019-09-04 08:50:54 【问题描述】:

我正在尝试聚合 NorthWind 表 ProductsCategories,以便我可以获得包含每个类别中产品数量的产品类别名称列表

到目前为止尝试的代码:

SELECT 
    Categories.CategoryName, Categories.CategoryID
FROM 
    Categories 
LEFT JOIN 
    Products ON Products.CategoryID = Categories.CategoryID;

上面的代码显示了类别。但是,当我对 Category ID 执行 Group by 时,它会显示一条错误消息

列“Categories.CategoryName”在选择列表中无效,因为它既不包含在聚合函数中,也不包含在 GROUP BY 子句中

我不知道出了什么问题。

注意:我是 SQL Server 新手

【问题讨论】:

提示:GROUP BYCOUNT(). @GordonLinoff.. 我试过 GROUP BY (Categories.CategoryID).count(Categories.CategoryName) 并抛出一个错误说“不能在 int 上调用方法” 提示,将计数移入 Select 子句@Biggboss2019 【参考方案1】:

GROUP BY 的正确语法是:

SELECT c.CategoryName, c.CategoryID, COUNT(p.CategoryID)
FROM Categories c LEFT JOIN
     Products p
    ON p.CategoryID = c.CategoryID
GROUP BY c.CategoryName, c.CategoryID;

请注意,这会引入表别名,使查询更易于编写和阅读。

SELECT 中的所有未聚合列都在GROUP BY 中。

【讨论】:

【参考方案2】:

添加 GROUP BY 后,您不能再引用原始集合中的任何元素,但出现在 GROUP BY 子句中的表达式或任何其他子句中的聚合函数除外。 原因是在 GROUP BY 之后,该集合将由每个组的一行组成,并且唯一保证相同的值是 GROUP BY 表达式。对于所有其他列,您必须保证一个值,而做到这一点的唯一方法是使用聚合函数 - 根据定义,它需要一组值,并返回一个值。 这就是为什么如果您按类别 ID 分组,则不能引用类别名称。 因为我猜在你的情况下它们在功能上是依赖的,你可以将两者都添加到 GROUP BY 子句中,或者将虚拟聚合添加到类别名称。

SELECT Categories.CategoryName, Categories.CategoryID, COUNT(*) AS CountProducts
FROM   Categories 
       LEFT JOIN 
       Products 
       ON Products.CategoryID=Categories.CategoryID
GROUP BY Categories.CategoryName, Categories.CategoryID

OR

SELECT MAX(Categories.CategoryName) AS CategoryName, Categories.CategoryID, COUNT(*) AS CountProducts
FROM   Categories 
       LEFT JOIN 
       Products 
       ON Products.CategoryID=Categories.CategoryID
GROUP BY Categories.CategoryID

【讨论】:

感谢您解释聚合和分组依据!

以上是关于如何在 NorthWind SQL Server 上执行聚合?的主要内容,如果未能解决你的问题,请参考以下文章

Northwind数据库不能在SQL Server 2012上创建

SQL Server调优系列基础篇(索引运算总结)

[SQL Server] 复制数据库任务

如何从SQL表中选择特定行并在SQL Server中连接多个表?

SQL Server调优系列基础篇

SQL Server调优系列基础篇(常用运算符总结——三种物理连接方式剖析)