sql - 未在 GROUP BY 原因或聚合函数中选择的列?
问题描述
我有一个数据库cats
,toys
它们之间的关系cat_toys
要查找拥有超过 5 个玩具的猫的名字,我有以下查询:
select
cats.name
from
cats
join
cat_toys on cats.id = cat_toys.cat_id
group by
cats.id
having
count(cat_toys.toy_id) > 7
order by
cats.name
列cats.name
未出现在聚合函数中group by
或未在聚合函数中使用,但此查询有效。相反,我无法选择cat_toys
表格中的任何内容。
这是 psql 的特别之处吗?
解决方案
这是您的查询:
select c.name
from cats c join
cat_toys ct
on c.id = ct.cat_id
group by c.id
having count(ct.toy_id) > 7
order by c.name;
您在问它为什么起作用:您正确地观察到c.id
它在group by
但不在select
-- 并且另一列在select
. 似乎错了。但事实并非如此。Postgres 支持标准中鲜为人知的部分,与聚合查询中的功能依赖相关。
让我避免使用技术术语。 cats.id
是 的主键cats
。这意味着id
是唯一的,因此知道id
指定来自 的所有其他列cats
。数据库知道这一点——它知道 的值name
对于给定的 总是相同的id
。因此,通过对主键进行聚合,您可以在不使用聚合函数的情况下访问其他列——这与标准一致。
这在文档中进行了解释:
当存在 GROUP BY 或存在任何聚合函数时,SELECT 列表表达式引用未分组的列是无效的,除非在聚合函数内或当未分组的列在功能上依赖于分组的列时,否则会有更多为未分组的列返回一个可能的值。如果分组列(或其子集)是包含未分组列的表的主键,则存在功能依赖性。
推荐阅读
- javascript - 如何访问从函数表达式返回的值?
- reactjs - react 是否允许传递语义上不同的子集?
- html - 如何从列表项中缩放画布?
- mysql - AWS Athena 中的 MYSQL
- reactjs - React 需要网络服务器吗?Web 应用服务器和 React 是如何通信的?
- websphere - 如何下载 com.ibm.ws.orb_8.5.0.jar
- javascript - 如何创建用于 TypeScript 泛型的 JavaScript 变量
- javascript - 在 React 功能组件中调用了两次 setTimeout 回调?
- python - 如何将输入整数限制为个位数?[Python]
- react-native - 在不使用输入字段的情况下确定在 React Native 上按下了哪个键