user1096685
user1096685

Reputation: 121

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

Upvotes: 1

Views: 152

Answers (6)

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.

Upvotes: 0

PapaSmurf
PapaSmurf

Reputation: 1035

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.

Upvotes: 0

Your Common Sense
Your Common Sense

Reputation: 157991

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.

Upvotes: 1

goat
goat

Reputation: 31854

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.

Upvotes: 0

Marcus
Marcus

Reputation: 12596

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

Upvotes: 3

leenix
leenix

Reputation: 76

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

Upvotes: 0

Related Questions