powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / DISTINCT ON & ORDER BY
13 сообщений из 13, страница 1 из 1
DISTINCT ON & ORDER BY
    #34643325
iu3116
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Задача: получить определённое колличество предложений с наименшими ценами, причём отели не должны повторятся.

SELECT DISTINCT ON (hotel) hotel,price FROM tures WHERE UPPER(region) = UPPER('Hurghada') ORDER BY price ASC LIMIT 10;
ERROR: SELECT DISTINCT ON expressions must match initial ORDER BY expressions

SELECT hotel,price FROM tures WHERE UPPER(region) = UPPER('Hurghada') ORDER BY price ASC limit 2;
hotel | price
---------+-------
Le Rois | 222
Le Rois | 258
(2 rows)


SELECT DISTINCT ON (hotel) hotel,price
FROM (
SELECT *
FROM tures WHERE
UPPER(region) = UPPER('Hurghada')
ORDER BY price ASC
LIMIT 2
) AS tmp
LIMIT 2;

hotel | price
---------+-------
Le Rois | 222
(1 row)

а нужно 2.


SELECT DISTINCT ON (hotel) hotel,price
FROM (
SELECT *
FROM tures WHERE
UPPER(region) = UPPER('Hurghada')
ORDER BY price ASC
LIMIT 2*10
) AS tmp
LIMIT 2;

hotel | price
-------------------+-------
El Samaka Beach | 306
El Samaka Comfort | 335
(2 rows)

т.е. не наименшии цены.

Как получить определённое колличество необходимых предложений?
...
Рейтинг: 0 / 0
DISTINCT ON & ORDER BY
    #34643489
LeXa NalBat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SELECT DISTINCT ON (hotel) hotel,price FROM tures WHERE UPPER(region) = UPPER('Hurghada') ORDER BY hotel,price ASC LIMIT 10;
...
Рейтинг: 0 / 0
DISTINCT ON & ORDER BY
    #34644351
Фотография Ёш
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SELECT hotel, min(price) FROM tures WHERE UPPER(region) = UPPER('Hurghada') GROUP BY hotel ORDER BY 2 LIMIT 10;
...
Рейтинг: 0 / 0
DISTINCT ON & ORDER BY
    #34644777
iu3116
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LeXa NalBatSELECT DISTINCT ON (hotel) hotel,price FROM tures WHERE UPPER(region) = UPPER('Hurghada') ORDER BY hotel,price ASC LIMIT 10;
он сначала сортирует по отелям а потом по цена, а нужно наоборот:
SELECT DISTINCT ON (hotel) hotel,price FROM tures WHERE UPPER(region) = UPPER('Hurghada') ORDER BY price,hotel ASC LIMIT 2;
ERROR: SELECT DISTINCT ON expressions must match initial ORDER BY expressions
...
Рейтинг: 0 / 0
DISTINCT ON & ORDER BY
    #34644786
iu3116
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЁшSELECT hotel, min(price) FROM tures WHERE UPPER(region) = UPPER('Hurghada') GROUP BY hotel ORDER BY 2 LIMIT 10;
hotel | min
-----------------+-----
Le Rois | 222
El Samaka Beach | 261
(2 rows)

Работает правильно, но слишком долго...
EXPLAIN ANALYZE SELECT hotel, min(price) FROM tures WHERE UPPER(region) = UPPER('Hurghada') GROUP BY hotel ORDER BY 2 LIMIT 2;
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------------
Limit (cost=285585.71..285585.72 rows=2 width=26) (actual time=38431.466..38431.483 rows=2 loops=1)
-> Sort (cost=285585.71..285585.73 rows=7 width=26) (actual time=38431.455..38431.459 rows=2 loops=1)
Sort Key: min(price)
-> HashAggregate (cost=285585.53..285585.61 rows=7 width=26) (actual time=38430.963..38431.186 rows=53 loops=1)
-> Seq Scan on tures (cost=0.00..285243.16 rows=68473 width=26) (actual time=49.620..38093.072 rows=69559 loops=1)
Filter: (upper((region)::text) = 'HURGHADA'::text)
Total runtime: 38431.584 ms
(7 rows)

Как можно оптимизровать?
...
Рейтинг: 0 / 0
DISTINCT ON & ORDER BY
    #34644968
Фотография Ёш
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
iu3116Как можно оптимизровать?Мне кажется или вопрос оптимизации не входит в обсуждаемую тему ? :) ищи по форуму. слишком мало информации что бы что нибудь сказать.

ps: совет "от балды" - попробуй создать функциональный индекс по региону: create INDEX tures_upper_region ON tures (UPPER(region));
...
Рейтинг: 0 / 0
DISTINCT ON & ORDER BY
    #34646600
LeXa NalBat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЁшSELECT hotel, min(price) FROM tures WHERE UPPER(region) = UPPER('Hurghada') GROUP BY hotel ORDER BY 2 LIMIT 10; iu3116Работает правильно, но слишком долго... Как можно оптимизровать?Это обсуждали в тынц , тынц , тыдынц .

PS: Конечно, как пососветовал Ёш, как минимум обязательно нужен индекс по upper(region). Либо поле region придется добавить в начало каждого индекса, которые упоминаются в обсуждениях по ссылкам.
...
Рейтинг: 0 / 0
DISTINCT ON & ORDER BY
    #34647031
iu3116
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ускорил таким запростом, но что-то он мне не нравится...
Проблема в том что нужно получить все данные а не только hotel,price
+LIMIT 2*10 узкое место.

SELECT *
FROM tures
WHERE id IN (
SELECT id
FROM (
SELECT *
FROM tures
WHERE UPPER(region) = UPPER('Hurghada')
ORDER BY price
LIMIT 2*10
) AS tmp
GROUP BY hotel,id
ORDER BY min(price)
LIMIT 2
);
...
Рейтинг: 0 / 0
DISTINCT ON & ORDER BY
    #34647177
LeXa NalBat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
iu3116Ускорил таким запростом, но что-то он мне не нравится...Да, он может дать неправильный результат, если 20 самый дешевых предложений принадлежат одному и тому же отелю. (И при этом в region-е отелей более одного.)

iu3116Проблема в том что нужно получить все данные а не только hotel,priceВсе нормально, дополнительный join по id, как вы сделали, не должен замедлить запрос. (При наличии индекса по id.)

iu3116GROUP BY hotel,idЗдесь опечатка? Должно быть "GROUP BY hotel"?
...
Рейтинг: 0 / 0
DISTINCT ON & ORDER BY
    #34647572
iu3116
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
iu3116GROUP BY hotel,idЗдесь опечатка? Должно быть "GROUP BY hotel"?[/quot]

ERROR: column "tmp.id" must appear in the GROUP BY clause or be used in an aggregate function
...
Рейтинг: 0 / 0
DISTINCT ON & ORDER BY
    #34647773
LeXa NalBat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
iu3116 LeXa NalBat iu3116GROUP BY hotel,idЗдесь опечатка? Должно быть "GROUP BY hotel"?ERROR: column "tmp.id" must appear in the GROUP BY clause or be used in an aggregate functionТо есть вообще получается, что такой запрос вернет два самых дешевых предложения от одного и того же отеля, если они самые дешевые в целом.

PS: можно попробовать такой запрос: SELECT * from ( SELECT DISTINCT ON (hotel) hotel,price FROM tures WHERE UPPER(region) = UPPER('Hurghada') ORDER BY hotel,price ) as A ORDER BY price ASC LIMIT 10;
...
Рейтинг: 0 / 0
DISTINCT ON & ORDER BY
    #34648307
iu3116
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторSELECT * from ( SELECT DISTINCT ON (hotel) hotel,price FROM tures WHERE UPPER(region) = UPPER('Hurghada') ORDER BY hotel,price ) as A ORDER BY price ASC LIMIT 10;

Работает, но крайне медленно. Индекс по hotel,price не помогает.
Я себе голову сломал над этими запросами, уже не соображаю нормально :)

P.S. Мож временную таблицу создать с минимальной ценой и id предложения для кажного отеля?
...
Рейтинг: 0 / 0
DISTINCT ON & ORDER BY
    #34648323
LeXa NalBat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
iu3116 авторSELECT * from ( SELECT DISTINCT ON (hotel) hotel,price FROM tures WHERE UPPER(region) = UPPER('Hurghada') ORDER BY hotel,price ) as A ORDER BY price ASC LIMIT 10;Работает, но крайне медленно. Индекс по hotel,price не помогает.Explain analyze покажите. Нужен индекс по (upper(region),hotel,price).
...
Рейтинг: 0 / 0
13 сообщений из 13, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / DISTINCT ON & ORDER BY
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]