SQLite与PostgreSQL中的分组

jmo0nnb3  于 2023-04-11  发布在  PostgreSQL
关注(0)|答案(2)|浏览(172)

在我最近的项目中,我一直在将使用SQLite的数据库迁移到PostgreSQL数据库。我一直在更新我的SQL代码以使用PostgreSQL,但一直在努力解决SQLite和PostgreSQL之间的一个差异,即分组。
例如,如果我想在SELECT子句中有多个值,但只想在一个字段上分组,在SQLite中这很容易。

  • item_id是外键 *
SELECT item_id, avg_price, min_price
FROM App_price
GROUP BY item_id

但是,在PostgreSQL中执行相同的查询会显示错误:
列“App_price.avg_price”必须出现在GROUP BY子句中或在聚合函数中使用
我唯一想分组的字段是item_id,所以我不想把avg_pricemin_price放在GROUP BY子句中。我也不想在这些字段上使用任何聚合函数。解决方案是什么?

vwkv1x7d

vwkv1x7d1#

如果SQLite返回一个随机行,则可以通过以下方式实现等效的行为:

SELECT DISTINCT ON (item_id) item_id, avg_price, min_price
  FROM App_price
 ORDER BY item_id;

正如@NickW指出的,SQLite的行为是非标准的,也是不符合逻辑的:选择随机行不是分组。

camsedfj

camsedfj2#

Postgres Group by
如果存在GROUP BY或任何聚合函数,则SELECT列表表达式引用未分组的列是无效的,除非在聚合函数中或未分组的列在功能上依赖于已分组的列。因为对于未分组的列,否则将有多个可能的值返回。如果分组的列(或其子集)是包含未分组列的表的主键。
Sqlite Group by *2.5.聚合查询中的裸列 *
如果正好有一分钟()或max()在查询中进行聚合,则结果集中的所有空列都从也包含最小值或最大值的输入行中获取值。因此在上面的查询中,输出中“B”列的值将是输入行中具有最大“c”值的“b”列的值。()和max():
如果在两行或多行中出现相同的最小值或最大值,则可以从这些行中的任何一行中选择裸值。选择是任意的。无法预测将从哪一行中选择裸值。对于同一查询中的不同裸列,选择可能不同。
如果查询中有两个或多个min()或max()聚合,则裸列值将从其中一个聚合具有最小值或最大值的行中获取。选择哪个min()或max()聚合决定裸列值的选择是任意的。对于同一查询中的不同裸列,选择可能不同。
这种对min()或max()聚合的特殊处理仅适用于这些聚合的内置实现。如果应用程序使用应用程序定义的替代项覆盖内置的min()或max()聚合,则为空列选择的值将从任意行中获取。
大多数其他SQL数据库引擎不允许空列。如果在查询中包含空列,其他数据库引擎通常会引发错误。在查询中包含空列的功能是SQL特定的扩展。
比如说

SELECT item_id, min(avg_price), min(min_price)
FROM App_price
GROUP BY item_id

我知道你说过你不想要聚合函数,但这是你必须要做的。即使你求助于子查询,avg_price和min_price基本上也是一些基本上随机的值。对于给定的分组字段(item_id),任何非分组的值都只是从帽子里挑出来的,并不是真正有用的。

相关问题