Selecting rows where out of two columns one is null - php

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

Related

php mysql search row with multiple arrays in cells

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?

Variable sql query depending on number of search parameter

I need to do a sql query in php for search some entries (so using WHERE). But the field used to search could be of variable number.
I have a page with a search form, with 4 Field. It sends via POST the fields to a search.php that make a query:
$gomme_sql = $data->query("SELECT * FROM table WHERE parameter1 = '$_POST['name1']' AND parameter2 = '$_POST['name2']' ORDER BY id ASC");
But I don't know which field are filled. So, if I don't enter anything in field1 from the search form, I shouldn't have parameter1 = '$_POST['name1']' in the WHERE query.
Have you any idea how to obtain this?
Thank you
You can check the post data before appending that clause to the query in a way like this:
edit: adding additional check:
$sql="select something from someTable ";
if(!empty($_POST['name1']) || !empty($_POST['name2'])) // add as many as you like
{
$sql.=" where ";
if(!empty($_POST['name1']))
{
$sql.="parameter1= $_POST['name1']";
}
// etc etc...
}
$sql.=" ORDER BY id ASC";
and so on.
Having said that, please, please use prepared statements with this sort of input from the user. This is SUPER open to sql injection. Please do read this: How can I prevent SQL injection in PHP?
You can write generic sql select function like this , if you need more complex SQL just modify it.
<?php
function sqlSelect($table, $sel, $wh = '', $groupby = '', $order = '', $add = '') {
$tb = $table;
if (is_array($table)) {
$tb = implode(',', $table);
}
if ($wh) {
if (is_array($wh)) {
$w = array();
foreach ($wh as $k => $v) {
$v = mysqli_real_escape_string($v);
if (is_null($v))
$w [] = "$k=null ";
else
$w [] = "$k ='$v'";
}
$wh = 'where ' . implode(' and ', $w);
}else {
$wh = "where $wh";
}
}
if ($groupby)
$groupby = "group by $groupby";
if ($order)
$order = "order by $order";
$sql = "select $sel from $tb $wh $groupby $order $add ";
return $sql;
}
//set _GET as this is console test
$_GET['name1']='Bob';
$where = array(
'name1'=>$_GET['name1']
);
echo sqlSelect('sometable' , '*' , $where) ."\n";
// select * from sometable where name1 ='Bob'
//or some complex stuff
echo sqlSelect('persons', "age,status" , array('name'=>'Maria' , 'likes'=>'PHP') , null, 'age' , 'limit 20');
//select age,status from persons where name ='Maria' and likes ='PHP' order by age limit 20

SQL Construction & PHP

I'm sure this is an easy question.
If you want to produce SQL with php for a search query. So you have say 5 criteria which are all optional and may or may not be inputted by the user. You cannot guarantee any of them.
When it comes to making the SQL in php you can use :
So if they exist then you can use AND for the 4 last criteria.
But for the first criteria if you have that as a WHERE if that one is not selected then the SQL just is a list of ANDs with no starting WHERE.
Is there an easy answer?
Code I've Written :
$sql = "
SELECT *
FROM Request, Rooms
WHERE Day = ".$Day." ";
if($ModCode != ''){
$sql .="AND ModCode = ".$ModCode." ";
}
if($StartTime != ''){
$sql .="AND StartTime = ".$StartTime." ";
}
if($Length != ''){
$sql .="AND Length = ".$Length." ";
}
if($Room != ''){
$sql .="AND Request.RoomID = Rooms.RoomID ";
$sql .='AND Rooms.RoomName = "'.$Room.'" ';
}
if($Room == '' && $Park != ''){
$sql .="AND Request.RoomID = Rooms.RoomID ";
$sql .='AND Rooms.Park = "'.$Park.'" ';
}
And now I want the bit WHERE Day = $Day to be optional like the others.
Cheers
You could store all criterias in an array and then implode AND between them:
if(!empty($array)) {
$where_part = "WHERE " . implode(" AND ", $array);
}
Update:
$cond = array();
if($ModCode != ''){
$cond[] = "ModCode = ".$ModCode;
}
if($StartTime != ''){
$cond[] = "StartTime = ".$StartTime;
}
if($Length != ''){
$cond[] = "Length = ".$Length;
}
if($Room != ''){
$cond[] = "Request.RoomID = Rooms.RoomID";
$cond[] = 'Rooms.RoomName = "'.$Room.'"';
}
if($Room == '' && $Park != ''){
$cond[] = "Request.RoomID = Rooms.RoomID";
$cond[] = 'Rooms.Park = "'.$Park.'"';
}
if(!empty($cond)) {
sql .= "WHERE " . implode(" AND ", $cond);
}
I dont think this would work.
For this kind of JOIN you always need a WHERE statement with a join condition.
And after adding it, the question will make sense no more.
However, if you need conditional JOIN as well as conditional WHERE, you had to state it in the question.
Anyway, the method is quite similar.
Store your wheres in an array and only impode the array into the query if its not empty.
Something like this;
$where = array();
//build up your where's in an array
$where[] = "searchField1='blah'";
$where[] = "searchField2='foo'";
//make your query and on the where only implode the array if its not empty else return null
$sqlQuery = "
Select
*
FROM
yourTable
".(empty($where)==false ? " WHERE ".implode(" AND ", $where) : null)."
ORDER BY x
";
where 1 = 1
and (name = ? or ? is null)
and (age = ? or ? is null)
question marks are just value placeholders. you get the point.
use prepared statements and bound parameters.
anyway, each of the parenthesized predicate conditions will evaluate to true of the placeholder value is null. make sure you differentiate between the sql keyword null, and "empty" or "falsy" values like 0 or empty string. The above requires type null.
I think I understand what you mean. You could split the query like so.
$sql = "SELECT * FROM `table` WHERE ";
$sql .= ($val1 == 1) ? "`field` = 'value' " : "1 = 1 ";
$sql .= ($val2 == 2) ? "AND `field` = 'value'" : "AND 1 = 1";
Edit: A quick fix would be to add a clause that would always be true.
In MySQL you have MATCH ... AGAINST
Like so:
SELECT id, header, message FROM table WHERE MATCH(header,message) AGAINST ('".mysql_real_escape_string($search)."' IN BOOLEAN MODE)
You can combine MATCH .. AGAINST with any other WHERE-clause, like:
WHERE id > 1000 AND MATCH (...) AGAINST ('searchstring' IN BOOLEAN MODE) AND date < NOW()
This does, however, require FULLTEXT searches to be possible, so it isn't very useful on TEXT-columns in InnoDB-tables for as far as I know. But it is the perfect solution to do searches in MyISAM tables, and you can use it on VARCHAR()-columns.

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

Checking for empty fields in mysql table

I have a table with 12 columns and 200 rows. I want to efficiently check for fields that are empty/null in this table using php/mysql. eg. "(col 3 row 30) is empty". Is there a function that can do that?
In brief: SELECT * FROM TABLE_PRODUCTS WHERE ANY COLUMN HAS EMPTY FIELDS.
empty != null
select * from table_products where column is null or column='';
SELECT * FROM table WHERE COLUMN IS NULL
As far as I know there's no function to check every column in MySQL, I guess you'll have to loop through the columns something like this...
$columns = array('column1','column2','column3');
foreach($columns as $column){
$where .= "$column = '' AND ";
}
$where = substr($where, 0, -4);
$result = mysql_query("SELECT * FROM table WHERE $where",$database_connection);
//do something with $result;
The = '' will get the empty fields for you.
you could always try this approach:
//do connection stuff beforehand
$tableName = "foo";
$q1 = <<<SQL
SELECT
CONCAT(
"SELECT * FROM $tableName WHERE" ,
GROUP_CONCAT(
'(' ,
'`' ,
column_name,
'`' ,
' is NULL OR ',
'`' ,
column_name ,
'`',
' = ""' , ')'
SEPARATOR ' OR ')
) AS foo
FROM
information_schema.columns
WHERE
table_name = "$tableName"
SQL;
$rows = mysql_query($q1);
if ($rows)
{
$row = mysql_fetch_array($rows);
$q2 = $row[0];
}
$null_blank_rows = mysql_query($q2);
// process the null / blank rows..
<?php
set_time_limit(1000);
$schematable = "schema.table";
$desc = mysql_query('describe '.$schematable) or die(mysql_error());
while ($row = mysql_fetch_array($desc)){
$field = $row['Field'];
$result = mysql_query('select * from '.$schematable.' where `'.$field.'` is not null or `'.$field.'` != ""');
if (mysql_num_rows($result) == 0){
echo $field.' has no data <br/>';
}
}
?>
$sql = "SELECT * FROM TABLE_PRODUCTS";
$res = mysql_query($sql);
$emptyFields = array();
while ($row = mysql_fetch_array($res)) {
foreach($row as $key => $field) {
if(empty($field)) || is_null($field) {
$emptyFields[] = sprintf('Field "%s" on entry "%d" is empty/null', $key, $row['table_primary_key']);
}
}
}
print_r($emptyFields);
Not tested so it might have typos but that's the main idea.
That's if you want to know exactly which column is empty or NULL.
Also it's not a very effective way to do it on a very big table, but should be fast with a 200 row long table. Perhaps there are neater solutions for handling your empty/null fields in your application that don't involve having to explicitly detect them like that but that depends on what you want to do :)
Check this code for empty field
$sql = "SELECT * FROM tablename WHERE condition";
$res = mysql_query($sql);
while ($row = mysql_fetch_assoc($res)) {
foreach($row as $key => $field) {
echo "<br>";
if(empty($row[$key])){
echo $key." : empty field :"."<br>";
}else{
echo $key." =" . $field."<br>"; 1
}
}
}
Here i'm using a table with name words
$show_lang = $db_conx -> query("SHOW COLUMNS FROM words");
while ($col = $show_lang -> fetch_assoc()) {
$field = $col['Field'];
$sel_lan = $db_conx -> query("SELECT * FROM words WHERE $field = '' ");
$word_count = mysqli_num_rows($sel_lan);
echo "the field ".$field." is empty at:";
if ($word_count != 0) {
while($fetch = $sel_lan -> fetch_array()){
echo "<br>id = ".$fetch['id']; //hope you have the field id...
}
}
}
There is no function like that but if other languages are allowed, you can extract the structure of a table and use that to generate the query.
If you only need this for a single table with 30 columns, it would be faster to write the query by hand...

Categories