如果我有以下表(例如使用postgresql,但可以是任何其他关系数据库),其中 car
有两把钥匙( id
以及 vin
):
create table car (
id int primary key not null,
color varchar(10),
brand varchar(10),
vin char(17) unique not null
);
create table appraisal (
id int primary key not null,
recorded date not null,
car_id int references car (id),
car_vin char(17) references car (vin),
price int
);
我可以成功地包括 c.color
以及 c.brand
因为它们依赖于 c.id
:
select
c.id, c.color, c.brand,
min(price) as min_appraisal,
max(price) as max_appraisal
from car c
left join appraisal a on a.car_id = c.id
group by c.id; -- c.color, c.brand are not needed here
但是,以下查询失败,因为它不允许包含 c.color
以及 c.brand
在选择列表中,即使它确实依赖于 c.vin
(那是一个键)。
select
c.vin, c.color, c.brand,
min(price) as min_appraisal,
max(price) as max_appraisal
from car c
left join appraisal a on a.car_vin = c.vin
group by c.vin; -- Why are c.color, c.brand needed here?
错误:错误:列“c.color”必须出现在GROUPBY子句中,或用于聚合函数位置:18
db fiddle中的示例。
1条答案
按热度按时间oewdyzsn1#
因为只有pk覆盖了
GROUP BY
条款。因此,您的第一个查询是有效的。一UNIQUE
约束不存在。不可延期的
UNIQUE
和一个NOT NULL
约束也可以限定。但这并没有实现——以及sql标准已知的一些其他函数依赖关系。该功能的主要作者peter eisentrat有更多的想法,但当时确定需求很低,相关成本可能很高。请参阅关于pgsql的特性的讨论。手册:
什么时候
GROUP BY
如果存在,或存在任何聚合函数,则对无效SELECT
列出引用未分组列的表达式,除非在聚合函数中或未分组列在功能上依赖于已分组列,否则未分组列可能返回多个值。如果分组列(或其子集)是包含未分组列的表的主键,则存在函数依赖关系。更明确地说:
postgresql识别函数依赖关系(允许从
GROUP BY
)仅当表的主键包含在GROUP BY
列表。sql标准指定了应该识别的附加条件。自
c.vin
是UNIQUE NOT NULL
,您可以改为使用pk列来修复第二个查询:另外,当引用完整性被强制执行并查询整个表时,两个给定的查询都可以便宜得多:在
appraisal
在加入之前。这样就不需要GROUP BY
在外面SELECT
先验的。比如:请参见:
一个查询中有多个array\u agg()调用
相关:
sql语句在mysql中工作在postgresql中不工作-sum&group\u by rails 3
postgresql-group by子句