[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Грамотный DISTINCT
Страницы: 1, 2
RCuPeR
Имеем таблицу личных сообщений с таким содержимым:
mysql> SELECT mail_id, preview, owner_user_id, viewer_user_id FROM phpfox_mail WHERE viewer_user_id = 38184;
+---------+------------------------------------------+---------------+----------------+
| mail_id | preview | owner_user_id | viewer_user_id |
+---------+------------------------------------------+---------------+----------------+
| 1 | Первое сообщение Роме | 5960 | 38184 |
| 3 | Второе сообщение Роме | 5960 | 38184 |
| 5 | Ау! Ау! Ау! | 6089 | 38184 |
| 17 | fdsfsdfsdfsdfsdsdfsdfsdfsdfsdf | 5960 | 38184 |
+---------+------------------------------------------+---------------+----------------+
4 rows in set (0.00 sec)


Где owner_user_id - айдишник отправителя, viewer_user_id - айдишник получателя (например меня).

Мне нужно вытянуть последние сообщения из диалога. Т.е.:

| 5 | Ау! Ау! Ау! | 6089 | 38184 |
| 17 | fdsfsdfsdfsdfsdsdfsdfsdfsdfsdf | 5960 | 38184 |



Пытался извратится так:
SELECT * FROM `phpfox_mail` WHERE `owner_user_id` IN (SELECT DISTINCT `owner_user_id` FROM `phpfox_mail` WHERE `viewer_user_id` = 38184)

не получилось.

_____________
Гнусный социопат с комплексом Бога.
Arh
Последнее собщение из диалога я так понял это SELECT MAX('mail_id ') WHERE (id отправителя равно 5960 и id получателя равно 38184) или (наоборот)

_____________
Промокод предоставляет скидку на заказ домена и/или хостинга reg.ru
BFCC-3895-8804-9ED2
RCuPeR
Цитата (Arh @ 16.04.2013 - 08:36)
Последнее собщение из диалога я так понял это SELECT MAX('mail_id ') WHERE (id отправителя равно 5960 и id получателя равно 38184) или (наоборот)

Да, все верно, но я не могу узнать id отправителя (owner_user_id), точнее составить точный запрос соответствия, подобное описано вами:
(id отправителя равно 5960 и id получателя равно 38184)

_____________
Гнусный социопат с комплексом Бога.
RCuPeR
Вот дамп, на всякий случай:
--
-- Структура таблицы `phpfox_mail`
--

CREATE TABLE IF NOT EXISTS `phpfox_mail` (
`mail_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`preview` varchar(255) DEFAULT NULL,
`owner_user_id` int(10) unsigned NOT NULL,
`viewer_user_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`mail_id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;

--
-- Дамп данных таблицы `phpfox_mail`
--

INSERT INTO `phpfox_mail` (`mail_id`, `preview`, `owner_user_id`, `viewer_user_id`) VALUES
(1, 'Первое сообщение Роме', 5960, 38184),
(3, 'Второе сообщение Роме', 5960, 38184),
(5, 'Ау! Ау! Ау!', 6089, 38184),
(17, 'fdsfsdfsdfsdfsdsdfsdfsdfsdfsdf', 5960, 38184);


_____________
Гнусный социопат с комплексом Бога.
Oyeme
Цитата
мне нужно вытянуть последние сообщения из диалога.


SELECT * FROM phpfox_mail  WHERE viewer_user_id = 38184 ORDER BY mail_id DESC LIMIT 2
Arh
Цитата (RCuPeR @ 16.04.2013 - 08:40)
но я не могу узнать id отправителя (owner_user_id)

Я пытаюсь понять как вы строите диалоги, не зная id отправителя.
Обычно список диалогов это id юзеров с кем переписывался данный пользователь, а просмотр конкретного диалога это все сообщения между двумя пользователями, то есть все id вроде всегда известны, так как диалог подразумевает двух переписчиков.

А если вы не знаете id отправителя то как вы хотите определить из какого диалога выводить последнее сообщение?

_____________
Промокод предоставляет скидку на заказ домена и/или хостинга reg.ru
BFCC-3895-8804-9ED2
RCuPeR
Цитата (Oyeme @ 16.04.2013 - 08:49)
Цитата
мне нужно вытянуть последние сообщения из диалога.


SELECT * FROM phpfox_mail  WHERE viewer_user_id = 38184 ORDER BY mail_id DESC LIMIT 2

Не катит, записей в таблице может быть over9000, а вытаскивает всегда две последние.
Вы не поняли проблему.

_____________
Гнусный социопат с комплексом Бога.
RCuPeR
Arh, попытаюсь описать.

Заранее айдишники отправителя мне неизвестны, знаю только id получателя, в нашем случае 38184.

Как я делал раньше:
зная свой айдишник я получал все сообщение адресованы мне, что-то типа
SELECT * FROM mail WHERE viewer_id = 38184

Потом, на стороне php я перебирал полученный массив и доставал из него айдишники отправителя.
Далее, я брал последнее сообщение из диалога (отравитель = owner_id AND получатель = 38184).
Это все работало, но это ужасный подход. При 100 диалогах, хоть по одному сообщению, в БД я буду посылать 101 запрос.
Нужно это все оптимизировать в один, пускай большой, но верный запрос на выборку.

_____________
Гнусный социопат с комплексом Бога.
Oyeme
Добавьте колонку с датой. wink.gif

В Вашем случаи не верное проектирование базы данных.
RCuPeR
Oyeme, я показал урезаный дамп БД, все самое нужное для примера.

Или под фразой "не верное проектирование базы данных" - вы подразумевали что-то другое?

_____________
Гнусный социопат с комплексом Бога.
Oyeme
Цитата (RCuPeR @ 16.04.2013 - 09:38)
Oyeme, я показал урезаный дамп БД, все самое нужное для примера.

Или под фразой "не верное проектирование базы данных" - вы подразумевали что-то другое?

Почему Вы не хотите использовать дату для того что бы просмотреть все последние сообщения которые отправили конкретному пользователю?
Arh
хз попробуй так )

owner_user_id тут 1


SELECT m.`viewer_user_id`,m2.`preview` FROM phpfox_mail m
LEFT JOIN (SELECT `preview`,`viewer_user_id`,`owner_user_id` FROM phpfox_mail
WHERE (`owner_user_id` = 1 OR `viewer_user_id` = 1) ORDER BY `mail_id` DESC) m2
ON m2.`viewer_user_id` = m.`viewer_user_id` OR m2.`owner_user_id` = m.`viewer_user_id`
WHERE m.`owner_user_id` = 1 GROUP BY m.`viewer_user_id`


должно вывести список диалогов с последним сообщением

_____________
Промокод предоставляет скидку на заказ домена и/или хостинга reg.ru
BFCC-3895-8804-9ED2
RCuPeR
Вот, допер :)

SELECT f.*
FROM (
SELECT `owner_user_id`, MAX(`mail_id`) AS `max_mail_id`
FROM `phpfox_mail`
WHERE `viewer_user_id`=38184
GROUP BY `owner_user_id`
ORDER BY NULL
) AS `d` INNER JOIN `phpfox_mail` AS `f` ON d.`owner_user_id` = f.`owner_user_id` AND d.`max_mail_id` = f.`mail_id`
ORDER BY f.`owner_user_id`


Arh, owner_user_id мне неизвестен :) Я его должен узнать в этом же запросе :)

_____________
Гнусный социопат с комплексом Бога.
Arh
Цитата (RCuPeR @ 16.04.2013 - 10:37)
Arh, owner_user_id мне неизвестен smile.gif Я его должен узнать в этом же запросе smile.gif

Ну поменяй в запросе owner и viewer местами))

_____________
Промокод предоставляет скидку на заказ домена и/или хостинга reg.ru
BFCC-3895-8804-9ED2
RCuPeR
Т.е., вот так:
SELECT m.`viewer_user_id`,m2.`preview` FROM phpfox_mail m
LEFT JOIN (SELECT `preview`,`viewer_user_id`,`owner_user_id` FROM phpfox_mail
WHERE (`viewer_user_id` = 38184) ORDER BY `mail_id` DESC) m2
ON m2.`viewer_user_id` = m.`viewer_user_id` OR m2.`viewer_user_id` = m.`owner_user_id`
WHERE m.`viewer_user_id` = 38184 GROUP BY m.`owner_user_id`


Не получилось :(

_____________
Гнусный социопат с комплексом Бога.
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.