Есть база на MySql. Задача базы - подобие записной книжки. Есть три таблицы Первая таблица - fio. Num - ключевое поле, идентификатор уникального человека в записной книжке, по его значению к конкретной записи привязываются адреса и телефоны, которых может быть несколько для одного человека. num fam name otch date 99 Зайцев Петр Викторович 1984-08-29 100 Величко Владислав Валентинович 1984-02-28 101 Денисович Денис Сергеевич 1984-01-01 вторая таблица - addr. собственно адреса. num city street home 99 Красноярск Металлургов 38 99 Красноярск Краснодарская 1 99 Красноярск Урванцева 17 100 Красноярск Металлургов 51 101 Красноярск Металлургов 38 101 Красноярск Краснодарская 1 101 Москва Аэровокзальная 12 третья таблица - phone. номера телефонов. num tel type 99 249121 Дом 99 89232845237 Сот 100 531498 Дом 100 89138392872 Сот 101 531297 Дом 101 89039888887 Сот проблема в том, как грамотней построить запрос. есть форма запроса на php с полем для каждого параметра, которые по сработке формы передаются другому скрипту, который делает запрос в базу. поиск должен осуществляться по любым полям. Например если ввести только телефон - должны выводится все люди с таким телефоном и со всеми данными, которые относятся к каждому из этих людей (адрес, имя, отчество и т.д.). Соответственно, в форме могут оставаться не заполненные поля. заранее спасибо за помощь )
Просьба не говорить, что эту базу можно сделать проще, в одну таблицу. В этом и суть задания, чтобы были три связанные таблицы
Первое, что приходит в голову :lol: Код (Text): SELECT f.num, f.fam, f.name, f.otch, f.date, a.city, a.street, a.home, p.tel, p.type FROM `fio` f LEFT JOIN `addr` a ON (a.num=f.num) LEFT JOIN `phone` p ON (f.num=p.num) WHERE [...] GROUP BY f.num; Где [...] - это условия LIKE или = для заполненных полей. Вот точно - пока пишу это, кто-то уже ответил )
Селект сразу на три таблицы? пишу так SELECT * FROM phone, fio, addr WHERE phone.tel='$tel' and fio.name='$nam' and ... и т.д. а если одно из условий в форме не было заполнено и переменная, где оно должно было быть пустая. тогда он не находит ничего, т.к. в таблице нету ни одной пустой ячейки. как тогда быть?
А ты не указывай в SQL запросе пустые ячейки. PHP: <? $sql=" [...] WHERE ".( $a ? "`a` = '".$a."' AND" : "")." ".( $b ? "`a` = '".$b."' AND" : "")." 1;"; ?>
про LIKE можно вместо Код (Text): `pole` = 'значение' написать Код (Text): `pole` LIKE '%значение%' тогда искаться будет не `pole`, которое равно 'значение', а поле, которое создержит 'значение'. % - означает, что там могут быть любые символы. А идея была составлять запрос "[..] WHERE `pole` LIKE '%".$pole."%'..." тогда, если $pole - пустая, будет `pole` LIKE '%%', т.е. любое. Но это, ИМХО, глупо. Поэтому смотри ниже. про ? : ... (условие ? действие_если_условие_верно : действие_если_условие_неверно) Если такая конструкция встречается при составлении строки, то вместо нее ставится "действие_если_условие_верно", если условие верно, и "действие_если_условие_неверно" в противном случае. В данном коде, если значение переменной задано - добавляется в запрос условия для проверки, в противном случае - условие не добавляется и эта пустая переменная просто не участвует в поиске. $sql=" [...] WHERE ". (ЕСЛИ ЕСТЬ $a ТО ДОБАВИТЬ "`a` = '$a' AND")." ".АНАЛОГИЧНО ДЛЯ $b." 1;"; На конце сформированного запроса будет AND. Чтобы закончить условие, не поменяв его значение, после AND ставим 1.
Спасибо. уже понятней. только еще бы разобраться и не запутаться где надо ставить " , а где ' .... а расскжажи, поржалуйста, про есть LEFT, что есть JOIN и что есть ON - в доках, которые у меня есть не нашел (
http://www.mysql.ru/docs/man/JOIN.html Текст запроса заключаешь в " ` - вокруг названий таблиц и полей ' ставишь там, где кавычка должна быть в запросе ".()." - там, где ты что-нибудь в запрос вставляешь. соответственно PHP: <? $sql=" [...] WHERE `имя поля` = '".(что-то)."';"; echo $sql; ?> выведет Код (Text): [...] WHERE `имя поля` = 'что-то'; Но это уже личное дело каждого, как писать
я решил сделать так: глянь плиз где ошибка (не работает): (там запрос на поиск по двум полям - имя и телефон) Код (Text): $dan=mysql_query("SELECT * FROM phone, fio, addr WHERE ".( $tel ? "`phone.tel` = '".$tel."' AND" : "")." ".( $nam ? "`fio.name` = '".$nam."' AND" : "")." 1;"; GROUP BY fio.num"); while($row = mysql_fetch_object($dan)) { echo $row->num,"<br>"; echo $row->nam,"<br>"; echo $row->tel,"<br>"; }
PHP: $dan=mysql_query("SELECT * FROM phone, fio, addr WHERE ".( $tel ? "`phone.tel` = '".$tel."' AND" : "")." ".( $nam ? "`fio.name` = '".$nam."' AND" : "")." 1 GROUP BY fio.num"); while($row = mysql_fetch_object($dan)) { echo $row->num."<br>"; echo $row->nam."<br>"; echo $row->tel."<br>"; }
эхххх. все-равно не работает вот так работает - но без фильтра на пустые поля: Код (Text): $dan=mysql_query("SELECT * FROM phone, fio, addr WHERE phone.tel='$tel' and fio.name='$nam' GROUP BY fio.num "); а так как ты написал - нет буду очень благодарен, если отладишь у себя и еще раз проверишь
А. Точно! Если ты пишешь table.field, то ` вокруг имени не нужны. PHP: $dan=mysql_query("SELECT * FROM phone, fio, addr WHERE ".( $tel ? "phone.tel = '".$tel."' AND" : "")." ".( $nam ? "fio.name = '".$nam."' AND" : "")." 1 GROUP BY fio.num"); while($row = mysql_fetch_object($dan)) { echo $row->num."<br>"; echo $row->nam."<br>"; echo $row->tel."<br>"; }
Огромное спасибо. есть же хорошие люди но только еще одна проблема. вернемся к начальному вопросу - сделать запрос. я делаю так Код (Text): $dan=mysql_query("SELECT * FROM phone, fio, addr WHERE ".( $nam ? "fio.name = '".$nam."' AND" : "")." ".( $fam ? "fio.fam = '".$fam."' AND" : "")." ".( $otch ? "fio.otch = '".$otch."' AND" : "")." ".( $a1 ? "addr.city = '".$a1."' AND" : "")." ".( $a2 ? "addr.street = '".$a2."' AND" : "")." ".( $a3 ? "addr.home = '".$a3."' AND" : "")." ".( $tel ? "phone.tel = '".$tel."' AND" : "")." 1 GROUP BY fio.num"); while($row = mysql_fetch_object($dan)) { echo $row->num."<br>"; echo $row->name."<br>"; echo $row->fam."<br>"; echo $row->otch."<br>"; echo $row->city."<br>"; echo $row->street."<br>"; echo $row->home."<br>"; echo $row->tel."<br>"; } во-первых, он возвращает не тот num, который соответствует человеку во-вторых, если ввести только не телефон, то он выводит всех людей в базе и говорит, что у каждого из них такой телефон
А если так? PHP: $dan=mysql_query("SELECT p.*,f.*,a.* FROM phone p LEFT JOIN fio f ON(f.num=p.num) LEFT JOIN addr a ON (a.num=p.num) WHERE ".( $nam ? "fio.name = '".$nam."' AND" : "")." ".( $fam ? "fio.fam = '".$fam."' AND" : "")." ".( $otch ? "fio.otch = '".$otch."' AND" : "")." ".( $a1 ? "addr.city = '".$a1."' AND" : "")." ".( $a2 ? "addr.street = '".$a2."' AND" : "")." ".( $a3 ? "addr.home = '".$a3."' AND" : "")." ".( $tel ? "phone.tel = '".$tel."' AND" : "")." 1 GROUP BY fio.num"); while($row = mysql_fetch_object($dan)) { echo $row->num."<br>"; echo $row->name."<br>"; echo $row->fam."<br>"; echo $row->otch."<br>"; echo $row->city."<br>"; echo $row->street."<br>"; echo $row->home."<br>"; echo $row->tel."<br>"; }
$dan=mysql_query("SELECT p.*,f.*,a.* FROM `phone` p LEFT JOIN `fio` f ON(f.num=p.num) LEFT JOIN `addr` a ON (a.num=p.num) WHERE ".( $nam ? "f.name = '".$nam."' AND" : "")." ".( $fam ? "f.fam = '".$fam."' AND" : "")." ".( $otch ? "f.otch = '".$otch."' AND" : "")." ".( $a1 ? "a.city = '".$a1."' AND" : "")." ".( $a2 ? "a.street = '".$a2."' AND" : "")." ".( $a3 ? "a.home = '".$a3."' AND" : "")." ".( $tel ? "p.tel = '".$tel."' AND" : "")." 1 GROUP BY f.num"); while($row = mysql_fetch_object($dan)) { echo $row->num."<br>"; echo $row->name."<br>"; echo $row->fam."<br>"; echo $row->otch."<br>"; echo $row->city."<br>"; echo $row->street."<br>"; echo $row->home."<br>"; echo $row->tel."<br>"; } Изменяя по кусочку (мускул в дауне - иду наощупь, т.ч. если выдает ошибки - говори какие).
все-равно. не работает. ошибки - не могу - пишу из блокнота - проверяю в браузере а может упростить задачу - сделать так чтобы возвращало только num записей лиц, которые подходят под критерий.
Ложная тревога - это я накосячил. все работает. огромнейшее спасибо вот если бы еще по полочкам разжевал сам селект
именно вот это все: Код (Text): SELECT p.*,f.*,a.* FROM `phone` p LEFT JOIN `fio` f ON(f.num=p.num) LEFT JOIN `addr` a ON (a.num=p.num)
и еще вопросик - по датам. работают все сравнения, кроме даты Код (Text): ".( $date ? "f.date = '".$date."' AND" : "")." $date получаю так: Код (Text): $day=$_POST["day"]; $mon=$_POST["mon"]; $year=$_POST["year"]; if($year!=""){ $date=$year."-".$mon."-".$day;}