Керування файлами cookie, які використовуються для реклами, таких як персоналізація реклами, ремаркетинг і аналіз ефективності реклами.
|
120tonn
12.01.2013 18:29
0
|
Доброго времени суток!
Имеются две таблицы: 1)mailing (письма): |id|time|num_comms(кол-во комментов)|cor(автор письма)|resp(получатели, может быть несколько, через запятую)|text|send| Запрос: $user_mail_all=mysql_query("SELECT * FROM `mailing` WHERE MATCH (resp) AGAINST ('$user_resp' IN BOOLEAN MODE) OR `cor`='$username' ORDER BY `id` DESC LIMIT ".$start.",".$per_page ) работает замечательно. (Здесь $user_resp=str_replace("-","tyre",$username) то есть убиреам возможное тире в имени пользователя для корректной работы поиска MATCH (resp) AGAINST(...), resp, разумеется, fooltext). 2)mail_views (запись количества комментариев к СВОИМ письмам, прочитанных юзером): |id|uid(ай-ди юзера)|lid(ай-ди письма)|time|number(количество комментов к этому письму на момент открытия его юзером)| Эта таблица нужна для вывода количества ответов на каждое письмо, оставленное после закрытия его адресатом или автором. Для показа новых ответов. И вот, такой запрос: $user_mail_all=mysql_query("SELECT * FROM `mailing` WHERE MATCH (resp) AGAINST ('$user_resp' IN BOOLEAN MODE) OR `cor`='$username' LEFT JOIN `mail_views` ON mailing.id=mail_views.lid AND mail_views.uid=".$_SESSION['uid']." ORDER BY `id` DESC LIMIT ".$start.",".$per_page) выдает такую ошибку: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'LEFT JOIN `mail_views` ON mailing.id=mail_views.lid AND mail_views.uid=12 ORDER ' at line 1 (Здесь 12 - это id пользователя, переданный в $_SESSION['uid']) Если убрать из запроса "MATCH (resp) AGAINST ('$user_resp' IN BOOLEAN MODE) OR ", оставив $user_mail_all=mysql_query("SELECT * FROM `mailing` WHERE `cor`='$username' LEFT JOIN `mail_views` ON mailing.id=mail_views.lid AND mail_views.uid=".$_SESSION['uid']." ORDER BY `id` DESC LIMIT ".$start.",".$per_page) ошибка сохраняется. Подскажите, пожалуйста, в чем дело? Спасибо. |
|
rudenko
12.01.2013 21:36
0
|
LEFT JOIN должен идти до условия WHERE:
SELECT * FROM `mailing` LEFT JOIN `mail_views` ON mailing.id=mail_views.lid AND mail_views.uid=".$_SESSION['uid']." WHERE MATCH (resp) AGAINST ('$user_resp' IN BOOLEAN MODE) OR `cor`='$username' ORDER BY `id` DESC LIMIT ".$start.",".$per_page |
|
120tonn
12.01.2013 22:16
0
|
Спасибо, Илья!
Мне уже разжевали проблему: stackoverflow.com/questions/14296021/left-join-not-works-after-match-against-in-boolean-mode Для тех, кто столкнется с чем-то подобным, хочу напомнить, что в случае с сортировкой (ORDER BY `id` DESC) первичные ключи обеих таблиц не должны называться одинаково. |
|
rudenko
12.01.2013 22:37
0
|
> первичные ключи обеих таблиц не должны называться одинаково
Это плохой совет Вам дали. Нужно просто алиасы в запросах использовать или полное название таблицы писать. Например так: ORDER BY mailing.id DESC |
|
120tonn
13.01.2013 20:59
0
|
Спасибо, Илья! И все-таки проблема...
Вот такая вот получилась конструкция: $user_mail_all=mysql_query("SELECT * FROM `mailing` LEFT JOIN `mail_views` ON mailing.id=mail_views.lid WHERE MATCH (resp) AGAINST ('$user_resp' IN BOOLEAN MODE) OR `cor`='$username' AND mail_views.uid=".$_SESSION['uid']." ORDER BY `id`DESC LIMIT ".$start.",".$per_page) or die(mysql_error()); В таблице `mailing` находятся письма, и пользователь может быть либо с столбце `cor` (если он - отправитель), либо в столбце `resp` (получатель, их может быть несколько, через запятую, где '$user_resp' - это наш '$username' с экранированным тире(если оно есть в имени пользователя)). В таблице `mail_views` хранятся записи о количестве ответов на письма, для того, чтобы подсвечивать новые. Суть проблемы. В этой редакции запроса, в которой идет поиск сначала получателей в столбце `resp`, письма получателям видны, они выводятся. Но отправитель (столбец `cor`) их не видит. Если же очередность условий запроса поменять местами, то есть, вместо: WHERE MATCH (resp) AGAINST ('$user_resp' IN BOOLEAN MODE) OR `cor`='$username' написать: WHERE `cor`='$username' OR MATCH (resp) AGAINST ('$user_resp' IN BOOLEAN MODE) выводятся только письма у отправителя, а уже получатели ничего на странице не видят. Почему?? |
|
rudenko
13.01.2013 23:45
0
|
Если это скрипт, который вы разрабатываете сами, то необходимо изменить структуру хранения данных - убрать хранение получателей через запятую. Сделайте для них отдельную таблицу. Это решит проблемы с выборками и уберет MATCH ... AGAINST, так как это используется только для полнотекстового поиска с релевантностью (это как с танка по воробьям стрелять), а вам нужна простая выборка where a='b' или where a in ('a', 'b'....). Если в условии есть OR и используется более 3-х сравнений, то нужны скобки, так как не понятно к чему OR относится. Например: a=1 or b=2 and c=3 варианты со скобками: (a=1 or b=2) and c=3 или a=1 or (b=2 and c=3) что даст разные результаты.
|
|
120tonn
13.01.2013 23:59
0
|
Ага, спасибо! Завтра привезут книгу по mysql - засяду за учебник. И мне нужно время, чтобы "увидеть" предлагаемую вами структуру базы, иначе я не могу.
Но проблема, кажись, решена: <?php $user_mail_all=mysql_query("SELECT * FROM `mailing` LEFT JOIN `mail_views` ON mailing.id=mail_views.vid WHERE MATCH (resp) AGAINST ('$user_resp' IN BOOLEAN MODE) OR `cor`='$username' ORDER BY `mailing`.`time` DESC LIMIT ".$start.",".$per_page) ?> Сделано почти наугад заменой ON mailing.id=mail_views.lid (где `mail_views`.`lid` - это ай-ди номер прочтенного текущим пользователем письма в таблице `mailing`, записанный в табл. `mail_views`) на: ON mailing.id=mail_views.vid (здесь `mail_views`.`vid` - это PRIMARY KEY табл. `mail_views`) Наугад, потому, что я плохо представляю себе, что такое и что делает оператор ON в LEFT JOIN. Поэтому не уверен в работоспособности этого фрагмента кода... |
Тема закрита.