我想运行以下查询:

SELECT DISTINCT ON (address_id) purchases.address_id, purchases.*
FROM purchases
WHERE purchases.product_id = 1
ORDER BY purchases.purchased_at DESC

但我有一个错误:

PG::Error:Error:SELECT DISTINCT ON表达式必须按表达式匹配初始顺序

添加address_id作为第一个ORDER BY表达式可以消除错误,但我真的不想添加排序超过address_id.有可能不在address_id点之前订购吗?

推荐答案

文件显示:

不同于(表达式[,…])的只保留给定表达式计算结果相等的每组行的第一行.[...] 请注意,每个集合的"第一行"是不可预测的,除非使用ORDER BY来确保所需的行首先出现.[...] DISTINCT ON表达式必须与最左边的ORDER BY表达式匹配.

Official documentation

所以你必须在订单上加上address_id.

或者,如果你正在寻找每address_id个包含最新购买产品的整行,并且结果按purchased_at排序,那么你正在try 解决一个最大的N个每组问题,该问题可以通过以下方法解决:

适用于大多数DBMS的通用解决方案:

SELECT t1.* FROM purchases t1
JOIN (
    SELECT address_id, max(purchased_at) max_purchased_at
    FROM purchases
    WHERE product_id = 1
    GROUP BY address_id
) t2
ON t1.address_id = t2.address_id AND t1.purchased_at = t2.max_purchased_at
ORDER BY t1.purchased_at DESC

一个基于@hkf答案的更面向PostgreSQL的解决方案:

SELECT * FROM (
  SELECT DISTINCT ON (address_id) *
  FROM purchases 
  WHERE product_id = 1
  ORDER BY address_id, purchased_at DESC
) t
ORDER BY purchased_at DESC

问题在此得到澄清、扩展和解决:Selecting rows ordered by some column and distinct on another

Sql相关问答推荐

如何从上一个值减go 值

LAG函数通过丢弃空值返回前一行

Postgres trunc_date删除一个月

更新其组的日期字段值小于最大日期减go 天数的记录

PostgreSQL 9.6嵌套的INSERT/RETURN语句的CTE性能低得令人无法接受

我怎样才能得到列值对应的最大值在另一个?

将Dense_RANK列为聚合(非解析)函数(&A)

在Postgres中合并相似的表

使用拆分器将已分组的不同值连接在一起

在Postgres,什么是;.USSTZ;在';YYYY-MM-DD;T;HH24:MI:SS.USSTZ';?

Grafana SQL 模板变量(值、文本)

我需要在 ASP.NET C# 中获取 2 个 SQL 查询结果的平均值

SQL 将 Varchar 转换为日期

多行状态下的分组查询判断状态

每组使用平均值来填补缺失值的SQL

如何在插入时将字符串'03-January-2023'转换为日期时间

COBOL\DB2作业(job)需要帮助?快来获取专业指导!

带聚合函数的 percentile_cont

根据是否存在值组合分组并 Select 行

条件意外地显着降低性能的地方