tgoop.com/sqlhub/2099
Create:
Last Update:
Last Update:
Нужен один «топ-элемент» на группу без оконных функций и лишних джойнов?
В PostgreSQL есть недооценённый приём: DISTINCT ON. Он берёт первую строку в каждой группе по указанным полям, какую именно, ты задаёшь через ORDER BY.
Так за один проход можно выбрать, например, последний заказ клиента, самую дорогую позицию в категории или актуальную запись по состоянию. Важно: в ORDER BY сначала идут поля из DISTINCT ON, а следом — критерий «топа» (например, created_at DESC).
Для скорости добавь составной индекс в том же порядке (ключи группировки → поле сортировки).
-- Возьмём по 1 строке на группу (g1, g2), выбирая «лучшую» по metric DESC
SELECT DISTINCT ON (g1, g2) *
FROM some_table
ORDER BY g1, g2, metric DESC;
-- Пример: последний заказ каждого пользователя
SELECT DISTINCT ON (o.user_id)
o.user_id, o.id AS order_id, o.created_at, o.total
FROM orders o
ORDER BY o.user_id, o.created_at DESC;
-- Рекомендуемый индекс для скорости (соответствует ORDER BY)
CREATE INDEX ON orders (user_id, created_at DESC);
-- Ещё пример: самая дорогая товарная позиция в категории
SELECT DISTINCT ON (p.category_id)
p.category_id, p.id, p.price
FROM products p
ORDER BY p.category_id, p.price DESC;
-- Индекс под этот запрос
CREATE INDEX ON products (category_id, price DESC);
@sqlhub
BY Data Science. SQL hub
Share with your friend now:
tgoop.com/sqlhub/2099