php mysql search row with multiple arrays in cells - php

ok, so stay with me here ...
i have a site with a table of about 80,000 rows; i am trying to search this table with one MySQL query. The problem is that each of the fields in the row i'm searching has / might have an array (ex: year = 2017,2016,2015, etc), and some of them may not have anything at all. i have tried doing a loop through to and build my "WHERE" clause as i pull the results, but that isn't working either.
any thoughts? any and all help will be greatly appreciated.
CODE:
INSERT INTO the table - this is one of the 13 different rows
if(!empty($_POST['pd_year']) && is_array($_POST['pd_year'])) {
$pd_year = implode(",", $_POST['pd_year']);
$insert_year = mysqli_query($con, "UPDATE prod_desigs_search_test SET pds_year = '$pd_year' WHERE s_id = '$search'");
} elseif(empty($_POST['pd_year'])) {
$insert_year = mysqli_query($con, "UPDATE prod_desigs_search_test SET pds_year = ' ' WHERE s_id = '$search'");
}
SELECT THE design and check if it is an array or not:
$get_search = mysqli_query($con, "SELECT * FROM prod_desigs_search_test WHERE s_id = '$s_id'");
while($new_search = mysqli_fetch_array($get_search)) {
$pd_year_ex = $new_search['pds_year'];
if(!empty($pd_year_ex) && is_array($pd_year_ex)) {
$pd_year = explode(",", $pd_year_ex, 0);
$year = $pd_year[0];
} elseif(!empty($pd_year_ex) && !is_array($pd_year_ex)) {
$year = $pd_year_ex;
}
$search = mysqli_query($con, "SELECT * FROM prod_designs WHERE pd_year = '$year'");
while($row_search = mysqli_fetch_array($search)) {
EDIT
I have tried to build out the "WHERE" in the query dependent on the is_array check like this:
$where = "WHERE ";
if(!empty($pd_year_ex) && is_array($pd_year_ex)) {
$pd_y = $pd_year[0];
foreach ($pd_y as $year) {
$where .= "pd_year LIKE '%".$year."%'";
}
} elseif(!empty($pd_year_ex) && !is_array($pd_year_ex)) {
$where .= "pd_year LIKE '%".$pd_year_ex."%'";
} elseif(empty($pd_year_ex)) {
$where .= "";
}
and this doesn't seem to be working either. i am just trying to understand how to do a search like this:
$search = mysqli_query($con, "SELECT * FROM designs WHERE pd_year LIKE '%2017,2016,2015%'")(etc)
I know it won't go with the above, but how do i search a table for something like this?

Related

Selecting rows where out of two columns one is null

Out of two search selections if a visitor select one only there is no search result. Following is my sql query:
$sql = "SELECT * FROM table WHERE column1='$column1' AND column2 ='$column2' ORDER BY id DESC
If I use 'OR' or otherwise I got wrong result in pagination. What should be right coding if a visitor opted only one criteria to search he will get result in first and subsequent pages?
In PHP construct your query:
$where = [];
$params = [];
if (!empty($column1)) {
$where[] = 'column1 = :column1';
$params[':column1'] = $column1;
} else {
$where[] = 'column1 IS NULL';
}
if (!empty($column2)) {
$where[] = 'column2 = :column2';
$params[':column2'] = $column2;
} else {
$where[] = 'column2 IS NULL';
}
if (!empty($where)) {
$pdo
->prepare("SELECT * FROM table WHERE ".implode(' AND ', $where))
->execute($params);
}
If you allow selection only by one column, remove else parts
A fast solution is that you can put the filters into a variable checking if the values of $column1 or $column2 it's filled and add after that in the SELECT clause:
$where_column = 'WHERE ';
if ($column1 != false)
$where_column .= "column1='$column1'";
if ($column2 != false) {
if ($where_column != 'WHERE') {
$where_column .= "AND column2='$column2'";
else
$where_column = "column2='$column2'";
}
}
$sql = "SELECT * FROM table $where_column ORDER BY id DESC

Problems with using PDO to perform an advanced search query

I have the following code and all of the search functions work except for the title field. So I can search by genre, date, location etc... but not by title. When attempting to search by title nothing is returned at all. Can anyone help me with this?
Also, is there a more efficient way to count all the fields before limiting it for use in pagination later on?
$today = date("Y-m-d");
$query = "SELECT * FROM TABLE_NAME WHERE Date >= '$today'";
$bind = Array();
if ($_GET["Title"] && $_GET["Title"] != "") {
$query .= " and Title like %?%";
$bind['Title'] = $_GET['Title'];
}
if ($_GET["Genre"] && $_GET["Genre"] != "") {
$query .= " and Genre like %?%";
$bind['Genre'] = $_GET['Genre'];
}
if ($_GET["Location"] && $_GET["Location"] != "") {
$query .= " and Location like %?%";
$bind['Location'] = $_GET['Location'];
}
if ($_GET["Date"] && $_GET["Date"] != "") {
$query .= " and Date = %?%";
$bind['Date'] = $_GET['Date'];
}
$stmt = $db->prepare($query);
$stmt->execute($bind);
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
$num = count($rows);
$query .= " ORDER BY Date LIMIT $limit, 9";
$stmt = $db->prepare($query);
$stmt->execute($bind);
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
Edit: After everyone's help I thought I would post my now revised code for future reference. It turns out the other fields were not working, but instead due to the if statement all this was nested in the code simply wasn't being executed.
$today = date("Y-m-d");
$query = "SELECT * FROM TABLE_NAME WHERE Date >= '$today'";
$countq = "SELECT count(*) FROM TABLE_NAME WHERE Date >= '$today'";
$bind = Array();
if ($_GET["Title"] && $_GET["Title"] != "") {
$query .= " and Title like :title";
$countq .= " and Title like :title";
$bind[':title'] = "%{$_GET['Title']}%";
}
if ($_GET["Genre"] && $_GET["Genre"] != "") {
$query .= " and Genre like :genre";
$countq .= " and Genre like :genre";
$bind[':genre'] = "%{$_GET['Genre']}%";
}
if ($_GET["Location"] && $_GET["Location"] != "") {
$query .= " and Location like :loc";
$countq .= " and Location like :loc";
$bind[':loc'] = "%{$_GET['Location']}%";
}
if ($_GET["Date"] && $_GET["Date"] != "") {
$query .= " and Date = :date";
$countq .= " and Date = :date";
$bind[':date'] = "{$_GET['Date']}";
}
$stmt = $db->prepare($countq);
$stmt->execute($bind);
$rows = $stmt->fetchAll();
$num = count($rows);
$query .= " ORDER BY Date LIMIT $limit, 9";
$stmt = $db->prepare($query);
$stmt->execute($bind);
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
all of the search functions work
With the given query it is not true
From PDO tag wiki:
placeholders cannot represent an arbitrary part of the query, but a complete data literal only. Neither part of literal, nor whatever complex expression or a syntax keyword can be substituted with prepared statement.
Prepare FULL literal first: $name = "%$name%"; and then bind it.
As for the "more" efficient method for pagination - yes, oh yes.
With your current way of counting data you don't actually need other queries. as you have ALL the data already and can paginate it as well.
But of course it will pollute all the memory soon. So, if you want to get a count of rows from database, get the very count: run the same query but instead of SELECT * make it "SELECT count(*)
There are not any errors returned, that's why I am so confused
From PDO tag wiki again:
It is essential to set ERRMODE_EXCEPTION as a connection option as it will let PDO throw exceptions on connection errors. And this mode is the only reliable way to handle PDO errors.

How to build a dynamic mysql query to suit all users

I need your help with my website search functionality. I'm developing a members area wherein users can search other registered users based on certain criteria, or combination of criteria.
My problem now is how to build a dynamic mysql query to suit the need of each combination of search criteria, where the number of criteria is variable.
Normally, I can write with a pre-determined set of criteria using
WHERE param1 = '$param1'
AND param2 = '$param2'
AND param3 = '$param3'
How do I solve this problem?
If the issue is that you don't know which of the criteria the user will pick, but want to return results for "blank" criteria, you can use the following:
$criteria_1 = $_POST['criteria_1'];
$criteria_2 = $_POST['criteria_2'];
$criteria_3 = $_POST['criteria_3'];
if(!$criteria_1 && !$criteria_2 && !$criteria_1) {
echo "You must select at least one criteria!";
} else {
// Run query mentioned below and return results.
}
THe query would then look like:
SELECT * from mytable
WHERE
(criteria1 = '$criteria_1' OR '$criteria_1' = '') AND
(criteria2 = '$criteria_2' OR '$criteria_2' = '') AND
(criteria3 = '$criteria_3' OR '$criteria_3' = '')
This will treat any blank (non-selected) parameters as blank and ignore them. Be aware that with the above, if no criteria are given, it will return all results.
Another way to write the above is:
SELECT * from mytable
WHERE
criteria1 IN ('$criteria_1', '') AND
criteria2 IN ('$criteria_2', '') AND
criteria3 IN ('$criteria_3', '')
Again, allowing for no entry at all to return all criteria1 results.
Here's a generic example of what you're asking:
$query = "SELECT * FROM mytable";
if ($_POST['name'] == "Jack") {
$query .= " WHERE name = 'Jack'";
}
if ($_POST['name'] == "Bob") {
$query .= " WHERE name = 'Bob'";
}
if ($_POST['state'] != "") {
$query .= " AND state = '" . mysql_real_escape_string($state) . "'";
}
//So now, in total, your query might look like this
//"SELECT * FROM mytable WHERE name = 'Bob' AND state = '$state'"
$result = mysql_query($query);
You just add to your $query string with if statements, then execute the query once you've checked all $_POST variables.
I've seen queries like this, so that if you don't want to put in a value for a particular column, you pass in NULL for that column:
SELECT *
FROM users
WHERE param1 = :param1
UNION
SELECT *
FROM users
WHERE param2 = :param2
UNION
SELECT *
FROM users
WHERE param3 = :param3
This assumes that you'll have each column indexed and you're performing Boolean AND searches (and using PDO).
use your scripting language (php) to loop over the inputs...
then have a structure like this:
WHERE 1=1
then add your
AND paramx = '$px'
to it...
$criteria = array();
//Populate your criteria and parameter arrays with input from the web page here
...
// $criteria should now have stuff in it
$sql = "SELECT * FROM mytable ";//Or whatever your sql query is
$count = 0;
foreach ($criteria as $key => $parameter) {
if ($count == 0) {
$sql = $sql."WHERE ".$key." = ".$parameter;
} else {
$sql = $sql."AND ".$key." = ".$parameter;
}
$count++;
}
That said, this is highly vulnerable to sql injection attack. Try using PHP PDO
An option is also to build the query from php/asp or whatever you working with, like this
$param1 = (isset($searchParam1) ? "param1 = $searchParam2" : "1");
$param2 = (isset($searchParam2) ? "param2 = $searchParam2" : "1");
$param3 = (isset($searchParam3) ? "param3 = $searchParam3" : "1");
and the query would be like
SELECT ... WHERE $param1 $param2 $param3
would like to share this code to build dynamic mysql query with PHP
Thx & regards
$vocabulary = (($page == "vocabulary") ? "image_name <> ''" : "");
$groupcat = (($group != "") ? "group = $group" : "");
$var = array($vocabulary, $groupcat);
$counter = "0";
$param = "";
for ($i=0;$i<count($var);$i++)
{
if ($counter == "0" && $var[$i] != "" ) $param = "WHERE ";
if ($counter > "0" && $var[$i] != "" ) $param = " AND ";
if ($param != "")
{
$condition .= $param . $var[$i];
$param="";
$counter++;
}
}
echo "Condition : ". $condition;

if field is empty, return all results

I'm working at a search script at the moment, but I have a little problem. I'm using the following query:
mysql_query("SELECT * FROM boeken WHERE
titel LIKE '%".$titel."%' AND
categorie_id = '".$categorie."' AND
auteurs LIKE '%".$auteurs."%' AND
jaar_copyright = '".$jaar_copyright."'
AND ontwerp_groep = '".$ontwerp_groep."'");
For example, when I search for 'categorie_id' = '5', and leave the other fiels empty, I want to get every row that has categorie_id = 5. No matter what the other fields are.
What it does is the following: I get every row that has categorie_id = 5, but where the title is empty, where the 'jaar_copyright' is empty, etc. etc.
How can I fix this the way I want?
<?php
$query = "SELECT * FROM boeken WHERE";
$n = 0;
$makeAnd = "";
foreach($_POST as $key=>$value){
if($value != '' && $value != 'submit'){
if($n != 0){$makeAnd = " AND";}
if(!is_numeric($value)){
$query .= "$makeAnd `$key` LIKE '%$value%'";
} else {
$query .= "$makeAnd `$key` = '$value'";
}
$n++;
}
}
print $query;
?>
In this way you can filter out empty values. If other values are posted to $_POST make sure to filter them out in the "if($value !=" part.
Why not just build a query based on vars? That way they're not included in the query unless the var is populated. I don't know what your variables like $titel actually are, so I just say if they're not blank. This should obviously be set towhatever is applicable. Not null, isset, etc. and always escape with something like mysql_real_escape_string()
$titel_where = "";
if($titel != '')
$title_where = "AND titel LIKE '%".$titel."%'";
$auteurs_where = "";
if($auteurs_where != "")
$auteurs_where = "AND auteurs LIKE '%".$auteurs."%'";
$jaar_copyright_where = "";
if($jaar_copyright != '')
$jaar_copyright_where = "AND jaar_copyright = '".$jaar_copyright."'";
$ontwerp_groep_where = "";
if($ontwerp_groep != '')
$ontwerp_groep_where = "AND ontwerp_groep = '".$ontwerp_groep."'";
mysql_query("SELECT * FROM boeken WHERE
categorie_id = '".$categorie."'
$titel_where
$auteurs_where
$jaar_copyright_where
$ontwerp_groep_where
");
mysql_query("SELECT * FROM boeken WHERE
( '".$categorie."' = 5 AND
categorie_id = 5
) OR
( titel LIKE '%".$titel."%' AND
categorie_id = '".$categorie."' AND
auteurs LIKE '%".$auteurs."%' AND
jaar_copyright = '".$jaar_copyright."' AND
ontwerp_groep = '".$ontwerp_groep."'
)");
For each criteria, you need to add a second evaluation for a blank parameter value:
(categorie_id = '".$categorie."' OR '".$categorie."' = '') AND ...
This way you cover both cases of an empty or a populated parameter.
EDIT:
Sample query as it would appear in SQL.
Assume you pass in a $categorie of 5 and no other parameters:
SELECT * FROM boeken WHERE
(titel LIKE '%%' OR '' = '' )AND
(categorie_id = '5' OR '5' = '') AND
(auteurs LIKE '%%' OR '' = '') AND
...
If they get passed in as NULL then do a NULL comparison instead of an empty string comparison.
You should check what field is set in code, and then only add that part to your query. for instance:
if(isset($_POST['categorie_id'])){
$where = " categorie_id = '".$categorie."' ";
}elseif(...){
....
}
Well, you get the point, you can make it a bit neater probably, depending on the format of your form/POST etc, but that's the idea. Just figure out WHAT you know, and then push it in the SQL.
I'm at work, so no long stories possible, but you should be able to figure it out with this:
foreach($_POST as $key=>$item){
if($value != ''){
$yourField = $key;
$yourValue = $item;
}
}
//PERFORM SANITY CHECKS!
//MAYBE USE PDO etc? (but that's another thing)
//SAVE them in 2 new variables used below:
$query = "SELECT * FROM boeken WHERE `$sanitizedField` = '$sanitizedValue'";

How can execute a MySQL query with multiple WHERE-clauses?

how would you do a mysql query where a user can choose from multiple options. Fox example I have a form that user can use to search for houses. Now I have a select box where you can chosse whether you want a house, a flat or whatever. Then I have a second box where you can choose for example the city you want the house or flat to be in. And maybe another one with the maximum price.
Now how would you do the mysql query? My problem is, I would do it like that:
if($_POST["house_type"] != 0) {
$select = mysql_query("SELECT * FROM whatever WHERE type = '".$_POST["house_type"]."'");
}
But now I only have the case that someone has chosen a house type but not any other option. So do I have to do an "if" for every possible combination of selected elements?
To emphasize my problem:
if(!isset($_POST["house_type"])) {
if($_POST["something"] == 0) {
$search_select = #mysql_query("SELECT * FROM housedata WHERE something = $_POST["whatever"]);
}
elseif($_POST["something"] != 0) {
$search_select = #mysql_query("SELECT * FROM housedata something = $_POST["whatever"] AND somethingelse = 'whatever');
}
}
elseif(!isset($_POST["house_type"])) {
if($_POST["something"] == 0) {
$search_select = #mysql_query("SELECT * FROM housedata WHERE something = $_POST["whatever"]);
}
elseif($_POST["something"] != 0) {
$search_select = #mysql_query("SELECT * FROM housedata something = $_POST["whatever"] AND somethingelse = 'whatever');
}
}
Now imagine I had like 10 or 20 different select boxes, input fields and checkboxes and I would have to do a mysql query depending on what of these boxes and fiels and checkboxes is filled. This would be a code that is extremely complicated, slow and horrible. So is there a possibility to make a mysql query like:
SELECT * FROM whatever WHERE house_data = '".$whatever."' AND (if(isset($_POST["something"])) { whatever = '".$whatever2."' } AND ...;
You get what I mean? Its a bit complicated to explain but actually its a very important question and probably easy to answer.
Thank you for your help!
phpheini
Generate the WHERE clause prior to running the SQL.
A short example:
$whereClause = "";
if ($_POST['opt1']) {
$opt1 = mysql_real_escape_string($_POST['opt1']);
$whereClause .= "AND opt1='$opt1'";
}
if ($_POST['opt2']) {
$opt2 = mysql_real_escape_string($_POST['opt2']);
$whereClause .= "AND opt2='$opt2'";
}
mysql_query("SELECT * FROM table WHERE 1 ".$whereClause);
To point you a little bit into the right direction, try something like this:
if(isset($_POST["something"]))
{
$where = " AND whatever = '".$whatever2."'";
}
else $where = '';
mysql_query("SELECT * FROM whatever WHERE house_data = '".$whatever."'".$where);
$where = array();
if($_POST["something"]) {
$where[] = " something =".$_POST["something"];
}
if($_POST["something2"]) {
$where[] = " something2=".$_POST["something2"];
}
.
.
.
//build where string
$where_ = !(empty($where) ? " WHERE ".implode(" AND ",$where) : "";
//build sql
$sql = "SELECT * ... ".$where;
write some simple query builder
$where = array();
if($_POST["something"]) {
$where[] = sprintf(" something='%s'",$_POST["something"]);
//sprintf - prevent SQL injection
}
if($_POST["something2"]) {
$where[] = sprintf(" something2='%s'",$_POST["something2"]);
}
//build where string
$where_str = " WHERE ".implode(" AND ",$where);
//build sql
$sql = "SELECT * ... $where_str";
You need to build your search string separately but the format is simply
SELECT * FROM your_table WHERE number = {$number} AND sentence = '{$sentence}';
Since you are creating the search term based on PHP logic do this:
$search = "SELECT * FROM your_table WHERE ";
if(isset($whatever)) $search .= "something = '{$whatever}'";
if(isset($whateverelse)) $search .= " AND somethingelse = '{$whateverelse}'";
$search_select = mysql_query($search);

Categories