X   Сообщение сайта
(Сообщение закроется через 3 секунды)



 

Здравствуйте, гость (

| Вход | Регистрация )

Открыть тему
Тема закрыта
> Вытаскивает по 2 значения
gaaarfild
gaaarfild
Topic Starter сообщение 18.6.2010, 16:33; Ответить: gaaarfild
Сообщение #1


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

"SELECT a.`id`, a.`message`, a.`from`, a.`to`, a.`send_time`, a.`readed`, b.`name` FROM ".$prefix."_messages AS a, ".$prefix."_users AS b WHERE (a.`from`=b.`id` OR a.`to`=b.`id`) AND (a.`from`=".$_POST['from']." AND a.`to`=".$_POST['to'].") OR (a.`from`=".$_POST['to']." AND a.`to`=".$_POST['from'].") ORDER BY a.`send_time` DESC"


Но проблема в том, что он вытаскивает по два раза каждое сообщение, хотя, вроде бы по логике, не должен бы.
В чем моя ошибка?
0
Вернуться в начало страницы
 
Ответить с цитированием данного сообщения
ZiTosS
ZiTosS
сообщение 19.6.2010, 18:10; Ответить: ZiTosS
Сообщение #2


gaaarfild, почитай про перекрестные запросы. У тебя тут явно условие, которое позволяет вытащить данные два раза.

Приведу простой пример, есть 2 таблицы:
tbl1
    id    name

    1    А
    2    Б
    3    В

tbl2
    id    name

    2    Г
    3    Д
    4    Е


И по запросу:
SELECT * FROM tbl1, tbl2

Получаем:
    id    name    id    letter

    1    А        2    Г
    2    Б        2    Г
    3    В        2    Г
    1    А        3    Д
    2    Б        3    Д
    3    В        3    Д
    1    А        4    Е
    2    Б        4    Е
    3    В        4    Е

Как видишь, перекрестный запрос по несколько раз вытаскивает записи, согласуя их друг с другом.

Тебя же должно было натолкнуть на мысль, что если у тебя повторение происходит 2 раза, значит, ошибка в том, что сообщения учитываются как со стороны отправителя, так и со стороны получателя.
Таким образом, как я понимаю, в твоём запросе условие (a.`from`=b.`id` OR a.`to`=b.`id`) приводит к получению подобного результата.

Чтобы избежать подобной ошибки, в данном случае нужно использовать объединение таблиц по первой, используя оператор LEFT JOIN, которая сопоставляет записи левой таблицы с существующими для них записями правой таблицы, и не делает перекрещивания.
Вернуться в начало страницы
 
Ответить с цитированием данного сообщения
gaaarfild
gaaarfild
Topic Starter сообщение 20.6.2010, 2:52; Ответить: gaaarfild
Сообщение #3


пробовал использовать. Ничего не поменялось. =)
Вернуться в начало страницы
 
Ответить с цитированием данного сообщения
ZiTosS
ZiTosS
сообщение 20.6.2010, 7:52; Ответить: ZiTosS
Сообщение #4


gaaarfild, проблема всё же в этом
(a.`from`=b.`id` OR a.`to`=b.`id`)

Ты за один прихват пытаешься сопоставить имя отправителя и имя получателя, чем приводишь к перекрестному объединению. Так как это ты пытаешься сделать в формате 2 таблиц. Сам себе это попробуй представить, ведь таблицы сопоставляются полями.

SELECT a.`id`, a.`message`, a.`from`, a.`to`, a.`send_time`, a.`readed`, b.`name` as name_to, c.`name` as name_from FROM {prefix}_messages a, {$prefix}_users b, {$prefix}_users c WHERE a.`to`=b.`id` AND a.`from`=c.`id` AND ((a.`from`={$_POST['from']} AND a.`to`={$_POST['to']}) OR (a.`from`={$_POST['to']} AND a.`to`={$_POST['from']})) ORDER BY a.`send_time` DESC

Кстати, не забываем о защите от инъекций... Что у тебя, по-моему, не сделано...
Вернуться в начало страницы
 
Ответить с цитированием данного сообщения
gaaarfild
gaaarfild
Topic Starter сообщение 20.6.2010, 22:28; Ответить: gaaarfild
Сообщение #5


Я в курсе про инъекции.
Система создана для внутреннего круга. Злоумышленники там не планируются. =)

Спасибо.
Вернуться в начало страницы
 
Ответить с цитированием данного сообщения
ZiTosS
ZiTosS
сообщение 20.6.2010, 22:54; Ответить: ZiTosS
Сообщение #6


gaaarfild, ты проверил, все работает?
Вернуться в начало страницы
 
Ответить с цитированием данного сообщения
gaaarfild
gaaarfild
Topic Starter сообщение 22.6.2010, 17:54; Ответить: gaaarfild
Сообщение #7


Почти. Вот чуток подправил, и теперь работает! =)

"SELECT a.`id`, a.`message`, a.`from`, a.`to`, a.`send_time`, a.`readed`, b.`name` AS name_to, c.`name` AS name_from FROM ".$prefix."_messages AS a, ".$prefix."_users AS b, ".$prefix."_users AS c WHERE a.`to`=b.`id` AND a.`from`=c.`id` AND ((a.`from`=".intval($_POST['from'])." AND a.`to`=".intval($_POST['to']).") OR (a.`from`=".intval($_POST['to'])." AND a.`to`=".intval($_POST['from']).")) ORDER BY a.`send_time` DESC"
Вернуться в начало страницы
 
Ответить с цитированием данного сообщения
ZiTosS
ZiTosS
сообщение 22.6.2010, 20:18; Ответить: ZiTosS
Сообщение #8


gaaarfild, тогда тему закрываю, вопрос решен.

Замечание модератора:
Эта тема была закрыта автоматически ввиду отсутствия активности в ней на протяжении 100+ дней.
Если Вы считаете ее актуальной и хотите оставить сообщение, то воспользуйтесь кнопкой
или обратитесь к любому из модераторов.


Поблагодарили: (0)
Вернуться в начало страницы
 
Ответить с цитированием данного сообщения
Открыть тему
Тема закрыта
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0


Свернуть

> Похожие темы

  Тема Ответов Автор Просмотров Последний ответ
Открытая тема (нет новых ответов) Как переместить значения ячеек таблицы при клике на первую (Javascript, Ajax, jQuery)
2 anethum 6751 2.9.2013, 13:08
автор: -RayOfLight-


 



RSS Текстовая версия Сейчас: 19.4.2024, 2:27
Дизайн