ドキュメントには次のように記載されています。
DISTINCT ON ( expression [, ...] ) は、指定された式が等しいと評価される行の各セットの最初の行のみを保持します。[...] ORDER BY を使用して目的の行が最初に表示されるようにしない限り、各セットの「最初の行」は予測できないことに注意してください。[...] DISTINCT ON 式は、一番左の ORDER BY 式と一致する必要があります。
公式文書
address_id
そのため、を order byに追加する必要があります。
または、それぞれの最新の購入製品を含む完全な行を探しており、address_id
その結果を並べ替えたpurchased_at
場合、次のアプローチで解決できるグループごとの最大 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
ここで問題が明確化され、拡張され、解決されました。ある列で並べられ、別の列で異なる行を選択する