Перейти к содержимому


Партнерская программа Kredov

  • Закрытая тема Тема закрыта

Вытаскивает по 2 значения

#1 gaaarfild

gaaarfild
  • Пользователь
  • 596 сообщений
  • Репутация: 0
0

Отправлено 18 Июнь 2010 - 15:33

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

"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

#2 ZiTosS

ZiTosS
  • Пользователь
  • 5 148 сообщений
  • Репутация: 8

Отправлено 19 Июнь 2010 - 17:10

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, которая сопоставляет записи левой таблицы с существующими для них записями правой таблицы, и не делает перекрещивания.
  • 0

#3 gaaarfild

gaaarfild
    Topic Starter
  • Пользователь
  • 596 сообщений
  • Репутация: 0

Отправлено 20 Июнь 2010 - 01:52

пробовал использовать. Ничего не поменялось. =)
  • 0

#4 ZiTosS

ZiTosS
  • Пользователь
  • 5 148 сообщений
  • Репутация: 8

Отправлено 20 Июнь 2010 - 06:52

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

Кстати, не забываем о защите от инъекций... Что у тебя, по-моему, не сделано...
  • 0

#5 gaaarfild

gaaarfild
    Topic Starter
  • Пользователь
  • 596 сообщений
  • Репутация: 0

Отправлено 20 Июнь 2010 - 21:28

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

Спасибо.
  • 0

#6 ZiTosS

ZiTosS
  • Пользователь
  • 5 148 сообщений
  • Репутация: 8

Отправлено 20 Июнь 2010 - 21:54

gaaarfild, ты проверил, все работает?
  • 0

#7 gaaarfild

gaaarfild
    Topic Starter
  • Пользователь
  • 596 сообщений
  • Репутация: 0

Отправлено 22 Июнь 2010 - 16:54

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

"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"

  • 0

#8 ZiTosS

ZiTosS
  • Пользователь
  • 5 148 сообщений
  • Репутация: 8

Отправлено 22 Июнь 2010 - 19:18

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

robot

robot
  • Пользователь PRO
  • 2 652 сообщений
  • Репутация: 85


Оформление форума – IPBSkins.ru