Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: вывод сообщений

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


 Страниц (1): [1]   

> Без описания
Богдан Скуба
Отправлено: 14 Июня, 2017 - 23:37:53
Post Id



Новичок


Покинул форум
Сообщений всего: 6
Дата рег-ции: Апр. 2017  


Помог: 0 раз(а)




Всем привет, у меня есть таблица : messages
id | sender | taker | message | date | value
нужно вывести последние сообщения всех диалогов отсортированых по date
все перепробовал ничего придумать или найти не могу
 
 Top
OrmaJever
Отправлено: 15 Июня, 2017 - 00:51:38
Post Id



Активный участник


Покинул форум
Сообщений всего: 7540
Дата рег-ции: Янв. 2010  
Откуда: Чернигов


Помог: 299 раз(а)




мускуль?


-----
Если вы хотя бы 3-4 раза не решите всё выкинуть и начать заново - вы явно что-то делаете не так.
 
 Top
Vladimir Kheifets
Отправлено: 15 Июня, 2017 - 08:34:01
Post Id



Частый посетитель


Покинул форум
Сообщений всего: 879
Дата рег-ции: Март 2017  
Откуда: Германия, Бавария


Помог: 37 раз(а)




Богдан Скуба пишет:
Всем привет, у меня есть таблица : messages
id | sender | taker | message | date | value
нужно вывести последние сообщения всех диалогов отсортированых по date
все перепробовал ничего придумать или найти не могу


Привет! Попробуйте так. Проверил. У меня работает.

CODE (SQL):
скопировать код в буфер обмена
  1. SELECT message FROM messages WHERE date = ( SELECT MAX(date) FROM messages)
 
 Top
Sail
Отправлено: 15 Июня, 2017 - 14:00:21
Post Id



Участник


Покинул форум
Сообщений всего: 1131
Дата рег-ции: Февр. 2014  


Помог: 57 раз(а)




Vladimir Kheifets, и получите все сообщения за последнюю дату.
Добавьте связку соотнесенного подзапроса с отправителем или получателем сообщения, чтобы идентифицировать диалог. Учтя при этом, что отправитель или получатель в одном диалоге могут участвовать в других диалогах, с другими получателями или отправителями...
При этом допускаем, что (судя по структуре таблички) между парой отправитель-получатель может вестись только один диалог...
 
 Top
OrmaJever
Отправлено: 15 Июня, 2017 - 20:46:17
Post Id



Активный участник


Покинул форум
Сообщений всего: 7540
Дата рег-ции: Янв. 2010  
Откуда: Чернигов


Помог: 299 раз(а)




раз ответа я не услышал то вот запрос для постгреса, а дальше сами переделывайте
CODE (SQL):
скопировать код в буфер обмена
  1. SELECT *
  2. FROM messages
  3. WHERE id IN (
  4.    SELECT max(id)
  5.    FROM messages
  6.    GROUP BY CASE WHEN sender > taker THEN taker || '-' || sender ELSE  sender || '-' || taker END;
  7.    ORDER BY date DESC
  8.    LIMIT 10
  9. )
  10. ORDER BY date


-----
Если вы хотя бы 3-4 раза не решите всё выкинуть и начать заново - вы явно что-то делаете не так.
 
 Top
Мелкий Супермодератор
Отправлено: 15 Июня, 2017 - 22:56:01
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




OrmaJever, запрос именно в постгресе работать не будет в принципе даже после правки синтаксической ошибки. Пошлёт нафиг за попытку сортировки по неаггрегатному полю.
А вот mysql при должном старании по части sql_mode как раз прожуёт. Правда, со случайным результатом.

Ну и seqscan гарантированный, да.

Постгресу можно как-то так index scan сделать по индексу sender, taker, date:
CODE (SQL):
скопировать код в буфер обмена
  1. WITH RECURSIVE t AS (
  2. (SELECT sender, taker, id FROM messages ORDER BY sender DESC, taker DESC, date DESC LIMIT 1)
  3. UNION ALL
  4. SELECT bpt.* FROM t, LATERAL (
  5. SELECT sender, taker, id FROM messages m WHERE (m.sender, m.taker)<(t.sender, t.taker)
  6. ORDER BY sender DESC, taker DESC, date DESC
  7. LIMIT 1
  8. ) AS bpt
  9. )
  10. SELECT * FROM messages WHERE id IN (SELECT max(t.id) FROM t GROUP BY least(t.sender), greatest(t.taker))

Что-то более нормальное как-то уже лениво придумывать там, где вообще-то нужна отдельная табличка со ссылкой на последнее сообщение.


-----
PostgreSQL DBA
 
 Top
OrmaJever
Отправлено: 16 Июня, 2017 - 16:18:48
Post Id



Активный участник


Покинул форум
Сообщений всего: 7540
Дата рег-ции: Янв. 2010  
Откуда: Чернигов


Помог: 299 раз(а)




Мелкий пишет:
Пошлёт нафиг за попытку сортировки по неаггрегатному полю.

согласен, не заметил, надо


Мелкий пишет:
Ну и seqscan гарантированный, да.

это да, но это из-за условия, в идеале нужно отдельное поле для обозначения диалога


-----
Если вы хотя бы 3-4 раза не решите всё выкинуть и начать заново - вы явно что-то делаете не так.
 
 Top
Vladimir Kheifets
Отправлено: 18 Июня, 2017 - 08:52:50
Post Id



Частый посетитель


Покинул форум
Сообщений всего: 879
Дата рег-ции: Март 2017  
Откуда: Германия, Бавария


Помог: 37 раз(а)




Sail пишет:
Vladimir Kheifets, и получите все сообщения за последнюю дату.
Добавьте связку соотнесенного подзапроса с отправителем или получателем сообщения, чтобы идентифицировать диалог. Учтя при этом, что отправитель или получатель в одном диалоге могут участвовать в других диалогах, с другими получателями или отправителями...
При этом допускаем, что (судя по структуре таблички) между парой отправитель-получатель может вестись только один диалог...


Из название поля "date" не следует, что тип поля также "date".
В данном случае, тип поля должен быть "datetime".
Исходя из этого я показал как найти последнее сообщение.
Конечно, Вы правы, что допускать можно всё, что угодно и если необходимо ставить дополнительные условия. MySQL справится.
 
 Top
Sail
Отправлено: 18 Июня, 2017 - 11:20:28
Post Id



Участник


Покинул форум
Сообщений всего: 1131
Дата рег-ции: Февр. 2014  


Помог: 57 раз(а)




Vladimir Kheifets пишет:
Из название поля "date" не следует, что тип поля также "date".
В данном случае, тип поля должен быть "datetime".
Исходя из этого я показал как найти последнее сообщение.

Суть не в детализации времени (в день, в час, в секунду...), а в том, что требуется не одно последнее сообщение всех диалогов, а последнее сообщение для каждого диалога.
 
 Top
Vladimir Kheifets
Отправлено: 22 Июня, 2017 - 15:11:14
Post Id



Частый посетитель


Покинул форум
Сообщений всего: 879
Дата рег-ции: Март 2017  
Откуда: Германия, Бавария


Помог: 37 раз(а)




Sail пишет:
Vladimir Kheifets пишет:
Из название поля "date" не следует, что тип поля также "date".
В данном случае, тип поля должен быть "datetime".
Исходя из этого я показал как найти последнее сообщение.

Суть не в детализации времени (в день, в час, в секунду...), а в том, что требуется не одно последнее сообщение всех диалогов, а последнее сообщение для каждого диалога.

Добрый день!
Прочтите, пожалуйста, вопрос, с корого началась тема:
Богдан Скуба пишет:
Всем привет, у меня есть таблица : messages
id | sender | taker | message | date | value
нужно вывести последние сообщения всех диалогов отсортированых по date
все перепробовал ничего придумать или найти не могу

Я понял так, что требуется "вывести последние сообщения всех диалогов", а не "последнее сообщение для каждого диалога".

(Отредактировано автором: 22 Июня, 2017 - 15:12:58)

 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« SQL и Архитектура БД »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB