views:

92

answers:

7

look at this table please

table
|id| |name| |order|

i must get the rows, where name = something and order = somevalue

so i write

select `id` from `table` where `name` = 'something' and `order` = 'somevalue'

but depend on php logic, sometimes i need to get all rows, where name = somethimg, independently of order value. i don't want to change the query structure, because in practise there are many number of fields, and possible count of queries will became very big. so i want to save the structure of query, and when i need to select just by name, i want to write something like this

select `id` from `table` where `name` = 'something' and `order` = any value 

is it possible?

thanks

A: 
SELECT id FROM table WHERE name='something'

If you don't specify and order= ... it will allow any values.

Lotus Notes
@Byron i don't want to change the query structure
Syom
Dynamically building SQL queries is a fact of life, and even if you do find a way to avoid doing so it will be inflexible and/or inefficient. If you have a reason for not wanting to use a logical design choice, then you should say it in your question so that you don't have to downvote everyone who gives a reasonable alternative.
Lotus Notes
+2  A: 

Well, it's kind of a hack, but if you really need to do this, it'll work like this:

select `id` from `table` where `name` = 'something' and `order` = `order`

Then you're just saying "wherever order is the same as itself", so it's always true.

Chad Birch
I would consider this changing the structure, since the syntax to refer to a field is not the same as that to refer to a string.
Michael Madsen
+2  A: 

No, this is not possible. You need to change the structure (optionally to a LIKE so you can use '%', but that's very ugly).

However, you don't need to write a different query to handle every possible combination. You can simply create the query dynamically:

//create base query
$query = "select `id` from `table` where `name` = 'something' ";

//add order if we need it
if ($use_order)
  $query .= "and `order` = 'somevalue' ";

//repeat for any other optional part

Note that you should of course still take proper measures to avoid SQL injection and other security issues - I have not included this here in order to keep things simple.

Michael Madsen
@Michael Madsen what is SQL injection? maybe you speak about mysql_real_escape_string() and such functions? i don't understand the meaning of "SQL injection "
Syom
@Syom: SQL injection is the act of providing data which affects the structure of the query, causing it to do something else than what it was supposed to do. mysql(i)_real_escape_string is indeed what most people use to prevent that (although parameterized queries are strictly speaking a better approach, but that's a different topic). If you want to know more, there are plenty of good resources, both on SO and available via Google. All I'm trying to say is that you still need to remember doing this sort of thing when building dynamically.
Michael Madsen
A: 

If you are using bound parameters, it would be impossible.

If you just substitute the values, you can do the following:

select `id` from `table` where `name` = 'something' and `order` = `order`
Quassnoi
A: 

I don't think you have any choice... Once you do a selection you can't "unfilter" and get more rows.

You should just use two queries-- either two independent queries, or one that selects on the name into a temp table, and then (optionally) one that further selects on the order attribute.

Platinum Azure
A: 

Like Chad said above, just set the column equal to itself. But be careful, on some platforms / install configurations, NULL != NULL:

select `id` from `table` where `name` = 'something' and coalesce(`order`,'') = coalesce(`order`,'')
Brock Weaver
NULL != NULL is actually the expected behavior, as defined in the SQL standard.
Michael Madsen
A: 

This is a common theme with database queries - you need a variable query depending on how much filtering you wish to apply to the data it queries. You could go the route of having your query repeated as a string throughout your code, but that is bad practice as it increases the complexity of the code needlessly. Chances for errors occur if you need to change the query for some reason, and have to change it in multiple places as a result.

The better solution is to create a function which builds the query for you execute:

function buildMyQuery($name, $order = null) {
    $sql = "SELECT `id` FROM `table` WHERE `name`='$name'";

    if ($order != null) {
        $sql .= " AND `order`='$order'";
    }

    return $sql;
}

You could then run this for just using the 'name' field:

$query = buildMyQuery("somename");

Or this for using both fields:

$query = buildMyQuery("somename", "someorder");

As someone mentioned above, this code is deliberately simplified and contains no contingency for possibly dangerous data passed in via $name or $order. You would need to use mysql_real_escape_string or something similar to clean the data first, at the beginning of the function before either piece of data is used.

Dynamic query generation is a fact of life as Byron says, so I would become accustomed to it now rather than using hack-ish workarounds.

Geoff Adams