Здраствуйте. Прошу прощение, если такая тема где то проскакивала.. просто обсмотрел уже не один форум, но решение именно этой цели не могу найти. Задача у меня состоим вот в чем: Есть форма в которой 3 <select>, в которые данные загружаются из базы: 1. Город (в базе как 'city') 2. Валюта (в базе как 'currency') 3. Тип объявления (в базе как 'type') ну и соответственно кнопка "Поиск". Мне нужно что бы совершался поиск по базе учитывая эти параметры. Сейчас мой вариант не понятно как работает, да и работает через раз(даже выкладывать сюда нету смысла). Если выбрать все три параметра в соответствии с каким то полем в базе, результат может быть. Если один из селектов оставить не выбранным, то ничего в результате нету. Ну вообще где то ошибку делаю, потому что такой для меня сложный поиск я еще ни разу не делал. Прошу помочь с реализацией данного задума, так как не знаю как по правильному такое сделать. Добавлено спустя 1 минуту 54 секунды: Если селект не выбран, какое ему нужно присваивать значение что бы он не учитывался в выборке из базы? Пробывал "" то я так понял оно и ищет пустое поле. Та же ситуация " " с пробелом.
То есть, переменная должна существовать только тогда, когда она не = "0".. Код (Text): if(@$_GET['city']!="0")$city=$_GET['city']; if(@$_GET['currency']!="0")$currency=$_GET['currency']; if(@$_GET['type']!="0")$type=$_GET['type']; Но с таким запросом, сортировка корректно работает только если искать по каждому параметру отдельно. Код (Text): $zzz="SELECT jb_board.id_category, jb_board.city, jb_board.cellphone, jb_board.expired, jb_board.exchange, jb_board.place, jb_board.type, jb_board.amount, jb_board.autor, DATE_FORMAT(jb_board.date_add,'%d.%m.%Y, %H:%i') AS dateAdd FROM jb_board WHERE city='".$city."' || id_category='".$currency."' || type='".$type."'"; Если выбрать к поиску еще один из трех параметров, или все три.. в ответ приходит каким то не понятным образом отсортированные данные.. К примеру в поле "валюта" все отлично. А вот в поле "город" там кроме выбранного города еще два города появляются. Два дня уже не могу понять почему так. Что именно делаю не так?
у тебя сейчас 3 GET, а вот если бы было больше, допустим 10, ты бы тоже все проверял через if? не проще использовать массив: Код (PHP): $data = array(); foreach(array('city', 'currency', 'type') as $key) { if ( isset($_GET[$key]) AND !empty($_GET[$key]) ) { $data[$key] = $_GET[$key]; } } если ты хочешь проверить задана ли переменная это делается при помощи isset, если переменная задана то будет возвращено TRUE empty проверяет не пуста ли переменная, если переменная ровна NULL или "" или 0 или FALSE, тогда будет возвращено TRUE PS и вообще запомни, ассоциативный массив в РНР это великая вещь, он очень сильно помогает уменьшит код, пользуйся им.
Ну тут согласен. Спасибо, буду разбираться. А как быть с некорректностью результата на запрос? Код (Text): $zzz="SELECT jb_board.id_category, jb_board.city, jb_board.cellphone, jb_board.expired, jb_board.exchange, jb_board.place, jb_board.type, jb_board.amount, jb_board.autor, DATE_FORMAT(jb_board.date_add,'%d.%m.%Y, %H:%i') AS dateAdd FROM jb_board WHERE city='".$city."' || id_category='".$currency."' || type='".$type."'";
Для начала перестаньте писать xуету вот эту: За "||" тимлиды ломают пальцы. Вам самому-то приятно читать такую галиматью? Есть общепринятый стиль написания длинных SQL запросов: Код (Text): SELECT jb.id_category, jb.city, jb.cellphone, jb.expired, jb.exchange, jb.place, jb.type, jb.amount, jb.autor, DATE_FORMAT(jb.date_add,'%d.%m.%Y, %H:%i') AS dateAdd FROM jb_board jb where jb.city = 1 OR jb.id_category = 2 OR jb.type = 3 И вот когда написан понятно запрос уже выясняйте почему в вашей выборке появляются две записи с разными городами. Очевидно потому, что что город в ваших условиях выборки у записей не должен совпадать. Если должен, то конструкцию OR меняйте на AND
в рунатах например на хабре обсуждалось http://habrahabr.ru/post/46068/ Актуальнее для многотабличных запросов, но лично я всегда стараюсь исповедовать такой принцип когда есть необходимость записывать длинный запрос целиком.
ну я как бы давно форматирую и длинные и короткие. меня смутила формулировка "общепринятый". это как стандарт кодирования уже получается. если есть общепринятое то наверное придется переучиваться, а если не общепринятое то можно сильно и не напрягаться. у меня как-то вот так получается: Код (Text): SELECT t.field, t.field1, ... FROM tbl t INNER JOIN table1 t1 ON t1.id=t.id INNER JOIN table2 t2 ON t2.id=t1.id WHERE 1=1 AND t.value='foo' AND t1.value='bar' GROUP BY t.field ORDER BY t.field
Нет общепринятый и стандарт кодирования совершенно разные вещи. Нормально получается. Ключевой момент читаемость.
Над конструкцией поработал. Если поменять на AND то по отдельности оно не хочет искать. Сразу дает нулевой результат. Если выбрать данные из всех трех селектов которые есть в базе, тогда результат есть! Но мне нужно что бы селекты и по отдельности работали. То есть, выбран один селект.. ну ладно, поищет по одному условию в базе.. есть два значит по двух.
Ну так вы смотрите какие у вас значения пришли из формы то! На их основе и подставляйте в запрос условия. Пришло 2 селекта - 2 AND Пришло 1 значение, соответственно, только одно условие. Если добавите радиобатон "Искать и/или", то, соответственно, если пришли 2 значения из селектов и переключатель включен на "искать ИЛИ", то в запросе будет два "или" вместо "и", в чем проблема?
Вы простите, я просто не слишком силён в таких вещах А как в запросе пишется условие? я просто с таким не сталкивался еще.
Что то я пытался найти и понять.. но если не сложно то покажите правильный вариант данной затеи и всё. Должно получиться что то типа такого бреда?) Код (Text): FROM jb_board where IF($city IS NOT NULL) THEN city='".$city."'; IF($id_category IS NOT NULL) THEN id_category='".$currency."'; IF($type IS NOT NULL) THEN type='".$type."';
Что за дикая каша у вас в голове? Смесь из php и mysql... Тут надо чётко разделить. mysql - отдельная программа, php - отдельная программа, программа на php формирует правильный SQL-запрос, уже в готовом виде передаёт его mysql (поскольку mysql - программа-сервер, она может принимать запросы от других программ и отдавать им ответы). Поэтому алгоритм должен быть таким: 1) Сформировать на основе поступивших данных запрос 2) Передать его программе mysql 3) Получить ответы и что-то с ними сделать Фильтры делаются примерно так: Код (PHP): $db = new mysqli(/*здесь параметры соединения с сервером mysql"); /* Заносим все условия в массив, чтоб потом их можно было удобно объединить одним оператором */ $consitions = []; if (isset($_GET["city"])) $conditions[] = "(city = " . (int) $_GET["city"] . ")"; if (isset($_GET["currency"])) // если валюта передаётся числовым id $conditions[] = "(currency= " . (int) $_GET["currency"] . ")"; // Следующее - если буквенным кодом //if (isset($_GET["currency"])) //$conditions[] = "(currency= '" . $db->real_escape_string($_GET["currency"] . "')"; $query = "select * from jb_board"; // Если были какие-то фильтры if (!empty($conditions)) { $query .= " where " . implode(" and ", $conditions); } // И т.д. для каждого условия, какие там фильтры у вас есть. // Готовый запрос (в нём уже нет самих переменных php, есть только их // значения - mysql не умеет читать переменные программы php!) // передаём в mysql $res = $db->query($query); // что-то делаем с результатом. Ну это конечно простейший случай, но думаю, вам есть о чём подумать
Переходить нужно от этой галиматьи к моделям нормальным давно. Упрощённо: Код (PHP): // разбор параметров запроса //... $query = 'SELECT ...'; $params = array(); $joiner = 'AND '; if (! empty($city)) { $params[] = "city=$city "; } if (! empty($type)) { $params[] = "type=$type "; } // ... if ( isset($search_type) AND $search_type == 'or') { $joiner = 'OR '; } if ( ! empty($params)) { $query .= ' WHERE ' . implode($joiner, $params); ) var_dump($query);
Спасибо большое))) Очень хороший вариант. И отдельное спасибо за описание. Немножко переделал под себя в некоторых местах. Все получилось, и работает)))
Показатель того, что полезно читать код используемых фреймворках. Так в Kohana работает Query Builder