2

I am writing a query that will retrieve data that match a set of criteria. Though the number and value of these criteria is unknown. It could be "name = username" and/or "date = today" and/or "title= hello" and so on.

There are almost 10 different criteria and there could be only one selected as there could be 10 of them, so writing a query for each scenario is not likely.

Does MySql have a syntax for such scenario ? If not what would be the best way to achieve that result ?

JohnFx
  • 34,542
  • 18
  • 104
  • 162
silkAdmin
  • 4,640
  • 10
  • 52
  • 83

2 Answers2

3

Columns and expressions in the WHERE clause must be fixed at the time you prepare the query. There's no way to parameterize columns or expressions in SQL.

The way most people solve this problem is by writing application code to add terms to your WHERE clause based on application logic and variables. In other words, append fragments of SQL syntax to a string inside code constructs like if (). The specific methods for doing this depend on the programming language you're using.

To help in this technique, sometimes frameworks provide a query builder API. For example, I worked on the Zend Framework, which includes a class called Zend_Db_Select. It helps you append terms to a query. The result is simply a string, which you can then prepare as an SQL statement.


I don't work on Drupal, but I see in their online manual they have an API method for adding terms to an SQL WHERE clause, similar to what I was describing above.

I suppose that if you had a PHP associative array of key/value pairs such that the key is the column name and the value is the value to search for, you could do this:

<?php

$query = ...  // create the query object

$search_conditions = array(
  name => "username",
  date => "today",
  title => "hello"
);

foreach ($search_conditions as $col => $val) {
  $query = $query->condition($col, $val, "=");
}

$query->execute();

The manuals says:

A conditional object consists of one or more conditional fragments that will all be joined by a specified conjunction. By default, that conjunction is AND.

So you can add zero, one, or more conditions to the query, and it keeps track of them, as if you had written the following:

WHERE name = :name AND date = :date AND title = :title

When it is time to execute the query, it automatically passes the values you gave ("username", "today", "hello") for those parameter placeholders.

Bill Karwin
  • 538,548
  • 86
  • 673
  • 828
  • wow.. I ll take your word that :) Thanks a lot, i ll make further test with this and post my results – silkAdmin Sep 19 '11 at 20:16
  • Oh and any chance you tried this with the Drupal 7 DB api ? I was hoping to pass an array to the condition() method of the Query object, though i haven't had luck with this so far. – silkAdmin Sep 19 '11 at 20:20
  • Thank you so much Bill, i really appreciate you taking the time of figuring that out. Many thanks again – silkAdmin Sep 19 '11 at 21:57
1

Another approach would be something like this if it has to be purse SQL and not a dynamically built SQL string in the client app.

SELECT * 
FROM Yourtable
WHERE (name=userNameParam OR userNameParam IS NULL) AND 
      (title=titleParam OR titleParam IS NULL) AND...

Note: This obviously won't work if you want to actually search for nulls in one of the fields.

JohnFx
  • 34,542
  • 18
  • 104
  • 162
  • Thanks for your input John that makes a lot of sense to, though i ll go for Bill answer as my query will probably look a little cleaner that way – silkAdmin Sep 19 '11 at 21:58
  • I agree that his answer is probably better. I just didn't know whether you needed a pure SQL solution or not so I wrote it assuming you did. – JohnFx Sep 19 '11 at 22:03