LINUX.ORG.RU

LEFT JOIN, NULL и where


0

0

второй день не могу придумать sql-запрос для поиска пользователей сайта..
задача вроде бы стандартная
допустим есть две таблицы :
основная: users - отсюда интересуют лишь поля id,nickname и sex
дополнительная: users_secondary - опциональная информация о пользователях(заполняется не всегда). интересующие поля weight, stature.

есть форма поиска, через которую юзер делает запросы:
допустим, это - nickname, пол, диапазон веса и роста.
причём, если юзер не ввел значение какого-либо из полей должны охватываться все записи.(к прим., если установлена лишь нижняя граница роста в 200см - должны выбираться все юзеры выше 200 и т.п.)

с незаполненными полями на первый взгляд всё просто. к прим. -
if (@$_POST['nickname']) { $nickname = $_POST['nickname']; } else { $nickname = '%'; }
if (@$_POST['weight0']) { $weight0 = $_POST['weight0']; } else { $weight0 = '0'; } и т.п.

первое что пришло в голову -

select u.id from users u left join users_secondary sec on u.id = sec.uid where u.nickname like '$nickname' and
u.sex = '$sex' and
sec.stature > '$stature0' and sec.stature < '$stature1' and
sec.weight > '$weight0' and sec.weight < '$weight1'
limit 100

но тут возникает проблема - если во второй таблице нет соотв-й записи LEFT JOIN возвращает его значением NULL и операторы сравнения в любом соучае вернут false..

как быть?

PS СУБД mysql

★★

Использовать дополнительно проверку значения на NULL.
Например вместо

  sec.weight > '$weight0' and sec.weight < '$weight1' 

использовать

  (sec.weight is NUll or (sec.weight > '$weight0' and sec.weight < '$weight1') )

Тогда будут выданы в запросе и клиенты у которых не определен вес. 

romanSA
()
Ответ на: комментарий от romanSA

2 romanSA
спасибо тебе, добрый человек : )

se ★★
() автор топика
Ответ на: комментарий от romanSA

ы.. если делать так -
(sec.weight is NUll or (sec.weight > '$weight0' and sec.weight < '$weight1') )
то возникает проблема - если задать лимит по возрасту, то он всё равно выведет все записи, которые имеют значение NULL : (

se ★★
() автор топика
Ответ на: комментарий от Selecter

Re>А если INNER JOIN?

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

se ★★
() автор топика
Ответ на: комментарий от romanSA

А еще можно использовать функцию IFNULL.

Например так

IFNULL(sec.weight,0)>='$weight0' and IFNULL(sec.weight,0)<'$weight1'

zhiltsov
()
Ответ на: комментарий от KRoN73

>Готовая SQL-инъекция.

А как её использовать?

А ничего, что $nickname в кавычках?

>like '$nickname' and

ps: кажется понял, как обойти кавычки, но всё равно, что можно туда всунуть?

smartly ★★★
()
Ответ на: комментарий от Casus

как это предотвратить? трансляция " в \" - поможет?

smartly ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.