Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / DISTINCT-ORDER BY и дубликаты / 13 сообщений из 13, страница 1 из 1
04.08.2015, 15:07
    #39022652
Random2
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DISTINCT-ORDER BY и дубликаты
Этим запросом:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
SELECT
	ID AS chat_id,
	last_msg,
	user_id
FROM
	(SELECT DISTINCT
			ON (chats. ID) chats. ID,
			chats.last_msg,
			chat_members.user_id
		FROM
			chat_members
		INNER JOIN chats ON chats. ID = chat_members.chat_id
		LEFT JOIN events ON events. ID = chats.event_id
		WHERE (chat_members.user_id = '187'
				OR chats.event_id IN (
					SELECT
						event_id
					FROM
						event_members
					WHERE
						user_id = '187'))
		AND chat_members.date_left IS NULL
		AND chats.event_id IS NOT NULL
		ORDER BY
			chats. ID,
			chats.last_msg,
			chat_members.user_id) AS T
ORDER BY last_msg DESC
LIMIT 5 OFFSET xxx



хочу извлечь из базы список чатов, чтобы небыло дубликатов по ID. Обязательное условие - сортировка по полю last_msg. Для этого сделал подзапрос. Извлекаю по 5 записей. На 2й странице ID чата встречается второй раз. Уже который час ломаю голову, почему так происходит. Ведь если извлечь все записи, то дубликатов нету. Соответственно, в подзапросе все впорядке. В основном запросе только ORDER BY и LIMIT, но с ними тоже вроде бы все правильно. Что я делаю не так?
...
Рейтинг: 0 / 0
04.08.2015, 15:16
    #39022660
Maxim Boguk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DISTINCT-ORDER BY и дубликаты
Random2,

покажите explain запроса...
на вскидку попробуйте добавить внутрь подзапроса OFFSET 0 может помочь.

--
Maxim Boguk
www.postgresql-consulting.ru
...
Рейтинг: 0 / 0
04.08.2015, 15:22
    #39022669
p2.
p2.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DISTINCT-ORDER BY и дубликаты
Random2На 2й странице ID чата встречается второй раз.по запросу не понять, уникально ли last_msg
...
Рейтинг: 0 / 0
04.08.2015, 15:39
    #39022685
Random2
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DISTINCT-ORDER BY и дубликаты
Результаты Explain:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
Limit  (cost=13.93..13.94 rows=5 width=24)
  ->  Sort  (cost=13.93..14.02 rows=34 width=24)
        Sort Key: chats.last_msg
        ->  Unique  (cost=12.86..13.03 rows=34 width=24)
              ->  Sort  (cost=12.86..12.94 rows=34 width=24)
                    Sort Key: chats.id, chats.last_msg, chat_members.user_id
                    ->  Hash Join  (cost=7.41..11.99 rows=34 width=24)
                          Hash Cond: (chat_members.chat_id = chats.id)
                          Join Filter: ((chat_members.user_id = 187::bigint) OR (hashed SubPlan 1))
                          ->  Seq Scan on chat_members  (cost=0.00..3.21 rows=121 width=16)
                                Filter: (date_left IS NULL)
                          ->  Hash  (cost=1.90..1.90 rows=45 width=24)
                                ->  Seq Scan on chats  (cost=0.00..1.90 rows=45 width=24)
                                      Filter: (event_id IS NOT NULL)
                          SubPlan 1
                            ->  Seq Scan on event_members  (cost=0.00..4.90 rows=20 width=8)
                                  Filter: (user_id = 187::bigint)



OFFSET 0 внутри подзапроса не помог. Результат совсем никак не изменился.

p2. , last_msg (int8) - UNIX TIMESTAMP, соответственно, может быть не уникальным.
...
Рейтинг: 0 / 0
04.08.2015, 15:48
    #39022697
Random2
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DISTINCT-ORDER BY и дубликаты
Результаты вывода основного запроса без разбиения на страницы:


Результаты вывода запроса с разбиением на страницы по 5:




Как видно, на 2й странице дублируется chat_id=71.

Заметил одну вещь - если в основном запросе после "ORDER BY last_msg DESC" добавить "chat_id", то дубликат пропадает. Но не пойму, почему. А в предыдущем варианте, где есть дубликаты, одного chat_id (104) не хватает, вместо него дубликат (71). Хотелось бы разобраться, почему так.
...
Рейтинг: 0 / 0
04.08.2015, 15:48
    #39022698
isdenno
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DISTINCT-ORDER BY и дубликаты
Random2,

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
SELECT DISTINCT
			ON (chats. ID) chats. ID,
			chats.last_msg,
			chat_members.user_id
		FROM
			chat_members
		INNER JOIN chats ON chats. ID = chat_members.chat_id
		LEFT JOIN events ON events. ID = chats.event_id
		WHERE (chat_members.user_id = '187'
				OR chats.event_id IN (
					SELECT
						event_id
					FROM
						event_members
					WHERE
						user_id = '187'))
		AND chat_members.date_left IS NULL
		AND chats.event_id IS NOT NULL
		ORDER BY
			chats. ID,
			chats.last_msg desc,
			chat_members.user_id
		limit 5 offset 5
...
Рейтинг: 0 / 0
04.08.2015, 15:52
    #39022701
Random2
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DISTINCT-ORDER BY и дубликаты
isdenno, спасибо за Ваш ответ, но обязательное условие - сортировка в результатах по last_msg
...
Рейтинг: 0 / 0
04.08.2015, 15:52
    #39022702
Maxim Boguk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DISTINCT-ORDER BY и дубликаты
Random2,

так порядок вывода равных строк при ORDER BY по строке он в общем неспецифицирован вообще.
Т.е. строки с last_msg NULL вообще можно считать что при order by last_msg располагаются как хотят и порядок между запросами может менятся вот он у вас и меняется, отсюда и дубликаты.

--
Maxim Boguk
www.postgresql-consulting.ru
...
Рейтинг: 0 / 0
04.08.2015, 15:57
    #39022710
isdenno
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DISTINCT-ORDER BY и дубликаты
Random2,
тогда
chats.last_msg desc,
chats. ID,
...
Рейтинг: 0 / 0
04.08.2015, 15:59
    #39022713
Random2
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DISTINCT-ORDER BY и дубликаты
Maxim Boguk, тогда достаточно добавить в основной запрос какую-нибудь еще сортировку по полю, которое не может быть пустым (например по chat_id, как я написал в последнем сообщении). Получается, это решит проблему, правильно?
...
Рейтинг: 0 / 0
04.08.2015, 16:10
    #39022725
Maxim Boguk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DISTINCT-ORDER BY и дубликаты
Random2Maxim Boguk, тогда достаточно добавить в основной запрос какую-нибудь еще сортировку по полю, которое не может быть пустым (например по chat_id, как я написал в последнем сообщении). Получается, это решит проблему, правильно?

Которое будет НЕ ТОЛЬКО не пустым но и уникальным по сочетанию полей указанных в order by.
Вариант по chat_id вполне рабочий с этой точки зрения, но я бы у заказчика бы поинтересовался на счет того какую именно он хочет сортировку при равных last_msg.

--
Maxim Boguk
www.postgresql-consulting.ru
...
Рейтинг: 0 / 0
04.08.2015, 16:10
    #39022726
Random2
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DISTINCT-ORDER BY и дубликаты
isdenno, так то работает. Но интересна причина. Наверное, как написал Maxim Boguk, причина в том, что нужно указывать сортировку дополнительно для не-нулевого поля.
...
Рейтинг: 0 / 0
04.08.2015, 16:12
    #39022729
Random2
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DISTINCT-ORDER BY и дубликаты
Maxim Boguk, спасибо за Вашу помощь! Теперь все стало на свои места.
...
Рейтинг: 0 / 0
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / DISTINCT-ORDER BY и дубликаты / 13 сообщений из 13, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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