[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: MYSQL: помогите составить запрос
p.pavluxa
Здравствуйте, уважаемые пользователи форума! Делается внутренняя почта.

Имеется таблица в которой хранятся сообщения:

CREATE TABLE IF NOT EXISTS `PrivateMessages` (
`iID` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '№',
`sCreateDate` datetime NOT NULL COMMENT 'Дата и время отправки',
`iSenderID` int(10) unsigned NOT NULL COMMENT '№ отправителя',
`sMessage` text NOT NULL COMMENT 'Сообщение',
`iRecipientID` int(10) unsigned NOT NULL COMMENT '№ получателя'
PRIMARY KEY (`iID`)
)
ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Приватные сообщения' AUTO_INCREMENT=1 ;


Зная № пользователя (который просматривает страницу) нужно получить список корреспондентов с которыми у него есть переписка (хотя бы одно сообщение отправленное/принятое). Для этого использую запрос вида:

SELECT IF( `iSenderID` = [id текущего пользователя], `iRecipientID`, `iSenderID` ) as `iCorrespondentID` 
FROM `PrivateMessages`
WHERE `iSenderID` = [id текущего пользователя] OR `iRecipientID` = [id текущего пользователя]
GROUP BY `iCorrespondentID`


Задача состоит в том, что по мимо его номера (корреспондента) нужно ещё получить дату и текст последнего сообщения. Как это осуществить?

Заранее всем благодарен за помощь.



Спустя 9 минут, 40 секунд (29.08.2012 - 11:31) Игорь_Vasinsky написал(а):
без структур таблиц и описания к ним -- трудновато гадать на кофейной гуще

Спустя 1 минута, 21 секунда (29.08.2012 - 11:32) p.pavluxa написал(а):
Я предоставил структуру и описание таблицы, она ни с чем не взаимодействует. Сама по себе существует. Задача получить с неё диалоги пользователей.

Спустя 13 минут, 19 секунд (29.08.2012 - 11:46) johniek_comp написал(а):
SELECT iRecipientID
FROM PrivateMessages
WHERE iSenderID = '{{текущий юзер}}'


получаешь список id-ков юзеров с которыми был контакт

Спустя 17 минут, 9 секунд (29.08.2012 - 12:03) p.pavluxa написал(а):
Это понятно. Но мне нужно получить дополнительно последнее сообщение.

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

Спустя 2 минуты, 58 секунд (29.08.2012 - 12:06) Игорь_Vasinsky написал(а):
упс.. прогялдел

(SELECT iRecipientID FROM PrivateMessages WHERE iSenderID = {id_user})
UNION
(SELECT sMessage,iRecipientID FROM PrivateMessages WHERE iSenderID = {id_user} ORDER BY iID DESC LIMIT 1)


так не пробывал?

Спустя 3 минуты, 35 секунд (29.08.2012 - 12:09) p.pavluxa написал(а):
Ошибка:
#1222 - The used SELECT statements have a different number of columns

Спустя 2 минуты, 11 секунд (29.08.2012 - 12:12) Игорь_Vasinsky написал(а):
ну мог бы и сам догадаться

(SELECT iRecipientID, iID FROM PrivateMessages WHERE iSenderID = {id_user})
UNION
(SELECT sMessage,iRecipientID FROM PrivateMessages WHERE iSenderID = {id_user} ORDER BY iID DESC LIMIT 1)

Спустя 1 минута, 24 секунды (29.08.2012 - 12:13) johniek_comp написал(а):
p.pavluxa
юнион работает только когда в двух таблицах одинаковое кол-во строк вернулось

Спустя 3 минуты, 8 секунд (29.08.2012 - 12:16) p.pavluxa написал(а):
Не работает. Какие есть ещё предложения?

Давайте рассмотрим задачу на примере, пусть в таблице такие данные:

id | дата | отправитель | сообщение | получатель
1 | ... | 2 | привет | 3
2 | ... | 3 | хай | 2
3 | ... | 2 | чем занимаешься? | 3
4 | ... | 2 | привет чувак! | 4
5 | ... | 4 | чо нада? | 2
6 | ... | 2 | та не, ничо | 4

Пусть мы смотрим диалоги пользователя № 2.
В результате нашего запроса мы должны получить:
дата | корреспондент | последнее сообщение
... | 3 | чем занимаешься?
... | 4 | та не, ничо

Спустя 3 минуты, 11 секунд (29.08.2012 - 12:19) Игорь_Vasinsky написал(а):
не строк вернулось, а полей задействовано. (вроде biggrin.gif )


ТС - что вернул SQL?

делай 2 запроса.

у тя mysqli? PDO? mysql?

Спустя 5 минут, 7 секунд (29.08.2012 - 12:24) p.pavluxa написал(а):
PDO. При user_id = 2, твой запрос вернул бред

iRecipientID iID
3 1
3 3

fasfasfas 3


Когда в таблице такое:

INSERT INTO `PrivateMessages` (`iID`, `sCreateDate`, `iSenderID`, `sMessage`, `iRecipientID`) VALUES
(1, '2012-08-29 12:06:46', 2, 'Привет! Как твои дела?', 3),
(
2, '2012-08-29 12:06:59', 3, 'Привет! Та нрмально, а твои?', 2),
(
3, '2012-08-29 12:56:55', 2, 'fasfasfas', 3),
(
4, '2012-08-29 13:15:32', 3, 'афыафыаыф', 2);

Спустя 3 минуты, 18 секунд (29.08.2012 - 12:28) Игорь_Vasinsky написал(а):
сортировка по sCreateDate

Спустя 1 минута, 48 секунд (29.08.2012 - 12:29) Игорь_Vasinsky написал(а):
(SELECT iRecipientID, iID FROM PrivateMessages WHERE iSenderID = {id_user} GROUP BY iSenderID)
UNION
(SELECT sMessage,iRecipientID FROM PrivateMessages WHERE iSenderID = {id_user} ORDER BY sCreateDate DESC LIMIT 1)

Спустя 20 секунд (29.08.2012 - 12:30) p.pavluxa написал(а):
Эт конечно хорошо, но проблему не решает. Вот если бы можно было бы вложенным запросом вернуть целых два поля а не одно, это бы решило проблему. Я бы просто сделал бы вложенный запрос в SELECT и получил два поля (sMessage и sCreateDate).

Тоже какой-то бредЖ

iRecipientID iID
3 1
fasfasfas 3

Спустя 28 секунд (29.08.2012 - 12:30) killer8080 написал(а):
Цитата (p.pavluxa @ 29.08.2012 - 12:21)
SELECT IF( `iSenderID` = [id текущего пользователя], `iRecipientID`, `iSenderID` ) as `iCorrespondentID`
FROM `PrivateMessages`
WHERE `iSenderID` = [id текущего пользователя] OR `iRecipientID` = [id текущего пользователя]
GROUP BY `iUserID`

Откуда взялось поле `iUserID`?

Спустя 1 минута, 49 секунд (29.08.2012 - 12:32) p.pavluxa написал(а):
То iCorrespondentID, опечаточка )

Спустя 8 минут, 36 секунд (29.08.2012 - 12:41) Игорь_Vasinsky написал(а):
мой запрос попробывал?

Спустя 1 минута, 27 секунд (29.08.2012 - 12:42) p.pavluxa написал(а):
Да. Он неверно сработал. Вернул

iRecipientID 	iID
3 1
fasfasfas 3

Спустя 5 минут, 35 секунд (29.08.2012 - 12:48) Игорь_Vasinsky написал(а):
ну може во втором запросе сравнивать по iRecipientID
я у тя уже запутался, чьё последее сообщение надо.

Спустя 2 минуты, 6 секунд (29.08.2012 - 12:50) p.pavluxa написал(а):
Нужно последнее сообщение диалога (входящее или исходящее)

Спустя 59 секунд (29.08.2012 - 12:51) Игорь_Vasinsky написал(а):
Цитата
(4, '2012-08-29 13:15:32', 3, 'афыафыаыф', 2);


это?

Спустя 1 минута, 34 секунды (29.08.2012 - 12:52) p.pavluxa написал(а):
Да

Спустя 1 минута, 22 секунды (29.08.2012 - 12:54) killer8080 написал(а):
Цитата (p.pavluxa @ 29.08.2012 - 13:50)
Нужно последнее сообщение диалога (входящее или исходящее)

А почему нельзя просто?
SELECT * 
FROM `PrivateMessages`
WHERE `iSenderID` = <userid> OR `iRecipientID` = <userid>
ORDER BY `iID` DESC
LIMIT
1

Спустя 2 минуты, 1 секунда (29.08.2012 - 12:56) p.pavluxa написал(а):
Потому что мне нужно последнее входяшее/исходящее сообщение по каждому уникальному собеседнику (у которого iSenderID != [ид текущего пользователя] либо iResipoentID != [ид текущего пользователя]). В результате получить список собеседников и по каждому последнее сообщение.

Спустя 5 минут, 6 секунд (29.08.2012 - 13:01) Игорь_Vasinsky написал(а):
Цитата
WHERE `iSenderID` = <userid> OR `iRecipientID` = <userid>

эти люди могли с кем нить ещё переписываться

есть мысль, но некогда

Спустя 4 минуты, 5 секунд (29.08.2012 - 13:05) p.pavluxa написал(а):
user posted image

Спустя 3 минуты, 26 секунд (29.08.2012 - 13:08) Игорь_Vasinsky написал(а):
логика такая

1й запрос собирает ID всех собеседников

2й ищет мессадж с UID - самого юзера + IN(.... все собеседники) - ну и сортировка и лимит 1


Спустя 10 минут, 59 секунд (29.08.2012 - 13:19) killer8080 написал(а):
p.pavluxa
так?
SELECT * , IF( `iSenderID` = <userid>, `iRecipientID` , `iSenderID` ) AS `iCorrespondentID` 
FROM (
SELECT *
FROM `PrivateMessages`
WHERE `iSenderID` = <userid> OR `iRecipientID` = <userid>
ORDER BY `iID` DESC
) AS `t`
GROUP BY `iCorrespondentID`

Цитата (Игорь_Vasinsky @ 29.08.2012 - 14:01)
Цитата
WHERE `iSenderID` = <userid> OR `iRecipientID` = <userid>


эти люди могли с кем нить ещё переписываться

есть мысль, но некогда

Нет, это переписки в которых участвовал юзер, как отправитель, или как получатель

Спустя 16 секунд (29.08.2012 - 13:20) p.pavluxa написал(а):
Это первый запрос, вроде правильно составил
(SELECT DISTINCT `iRecipientID` FROM `PrivateMessages` WHERE `iSenderID` = 2) 
UNION
(SELECT DISTINCT `iSenderID` FROM `PrivateMessages` WHERE `iRecipientID` = 2)

либо
SELECT IF( `iRecipientID` = 2, `iSenderID`, `iRecipientID` ) as `iCorrespondentID` FROM `XeronPrivateMessages` WHERE `iSenderID` = 2 OR `iRecipientID` = 2 GROUP By `iCorrespondentID`

Спустя 7 минут, 44 секунды (29.08.2012 - 13:27) p.pavluxa написал(а):
Вообщем не получается :-(

Спустя 5 минут, 34 секунды (29.08.2012 - 13:33) killer8080 написал(а):
Цитата (p.pavluxa @ 29.08.2012 - 14:27)
Вообщем не получается :-(

ты мой вариант хоть пробовал?

Спустя 4 минуты, 3 секунды (29.08.2012 - 13:37) p.pavluxa написал(а):
да но это ток половина

Спустя 11 минут, 16 секунд (29.08.2012 - 13:48) killer8080 написал(а):
Цитата (p.pavluxa @ 29.08.2012 - 14:37)
да но это ток половина


В смысле половина?

Спустя 12 минут, 55 секунд (29.08.2012 - 14:01) p.pavluxa написал(а):
от задачи

Спустя 2 минуты, 16 секунд (29.08.2012 - 14:03) killer8080 написал(а):
Цитата (p.pavluxa @ 29.08.2012 - 15:01)
от задачи

ну и в чем вторая половина задачи? Или нужно угадать? rolleyes.gif

Спустя 12 минут, 20 секунд (29.08.2012 - 14:16) p.pavluxa написал(а):
Оооо... Сорри тупанул )))

Супер! Это именно то что я хотел!

killer8080, спасибо большое! Вы гений!
Быстрый ответ:

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