Документация гласит:
DISTINCT ON (выражение [, ...]) сохраняет только первую строку каждого набора строк, где заданные выражения оцениваются как равные. [...] Обратите внимание, что «первая строка» каждого набора непредсказуема, если только ORDER BY не используется, чтобы гарантировать, что желаемая строка появляется первой. [...] Выражение (я) DISTINCT ON должно соответствовать крайнему левому выражению ORDER BY.
Официальная документация
Так что вам придется добавить address_id
в заказ по.
В качестве альтернативы, если вы ищете полную строку, содержащую самый последний приобретенный продукт для каждого address_id
и отсортированный результат, purchased_at
то вы пытаетесь решить проблему наибольшего N на группу, которая может быть решена с помощью следующих подходов:
Общее решение, которое должно работать в большинстве СУБД:
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
Более ориентированное на PostgreSQL решение, основанное на ответе @ hkf:
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
Здесь проблема прояснена, расширена и решена: выбор строк, упорядоченных по одному столбцу и отличающихся по другому