Мы используем cookie-файлы
Для оптимизации работы нашего сайта мы используем cookie-файлы. Продолжая использовать сайт, Вы соглашаетесь с использованием cookie-файлов.
  • UAH
  • USD
  • RUB
  • EUR
  • +38(044) 392-74-33  Киев
  • +38(057) 728-39-00  Харьков
  • +38(056) 794-38-31  Днепр
  • +38(032) 229-58-93  Львов
  • +38(048) 738-57-70  Одесса
  • +38(093) 170-15-42  Life
  • +38(067) 400-88-44  Киевстар
  • +38(095) 630-90-82  MTC
  • +1(888)393-24-51  USA, Toll free
  • +44(131)507-01-14  Great Britain
  • +7(499) 348-28-61  Москва

MySQL. WHERE MATCH () AGAINST ( IN BOOLEAN MODE) и LEFT JOIN в одном запросе

Форумы MySQL WHERE MATCH () AGAINST ( IN BOOLEAN MODE) и LEFT JOIN в одном запросе
120tonn
12.01.2013
хостинг: есть
домен: есть
WHERE MATCH () AGAINST ( IN BOOLEAN MODE) и LEFT JOIN в одном запросе
Доброго времени суток!
Имеются две таблицы:
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)

ошибка сохраняется.

Подскажите, пожалуйста, в чем дело?
Спасибо.
Илья
12.01.2013
хостинг: есть
домен: есть
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
хостинг: есть
домен: есть
Спасибо, Илья!
Мне уже разжевали проблему: http://stackoverflow.com/questions/...
Для тех, кто столкнется с чем-то подобным, хочу напомнить, что в случае с сортировкой (ORDER BY `id` DESC) первичные ключи обеих таблиц не должны называться одинаково.
Илья
12.01.2013
хостинг: есть
домен: есть
> первичные ключи обеих таблиц не должны называться одинаково
Это плохой совет Вам дали. Нужно просто алиасы в запросах использовать или полное название таблицы писать.
Например так: ORDER BY mailing.id DESC
120tonn
13.01.2013
хостинг: есть
домен: есть
Спасибо, Илья! И все-таки проблема...
Вот такая вот получилась конструкция:


$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)


выводятся только письма у отправителя, а уже получатели ничего на странице не видят.
Почему??
Илья
13.01.2013
хостинг: есть
домен: есть
Если это скрипт, который вы разрабатываете сами, то необходимо изменить структуру хранения данных - убрать хранение получателей через запятую. Сделайте для них отдельную таблицу. Это решит проблемы с выборками и уберет 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
хостинг: есть
домен: есть
Ага, спасибо! Завтра привезут книгу по 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. Поэтому не уверен в работоспособности этого фрагмента кода...
Участвовать в общении на этом форуме могут только
зарегистрированные пользователи.

Если вы уже зарегистрированы Вам необходимо войти на форум.

Тема закрыта по истечению срока давности.
Горячая линия
(044)
392 74 33
другие города