select ... where id = any value. is it possible? - php

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 = something, 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 become 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

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.

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.

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`

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.

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.

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`,'')

On reflection, I have a better answer. My colleague showed me a way this can be done.
My example...
Select rentals.* From rentals Where ((? = '') OR (user_id = ?))
The variables must be the same.
If they are both 5 for example, the first boolean will be false, but the second will be true, for the rows where the users id is 5.
If you require "all", setting as an empty string will result in all rows being seen to meet the where clause condition.

Can't you just use a not null query here?
select `id` from `table` where `name` = 'something' and `order` is not null;

You should be able to do it like this:
select `id` from `table` where `name` <>'' and `order` <>''
That will select anywhere that the value is not equal to blank.

$sql = "SELECT * FROM auctions WHERE id = id ";
if ($category !== "ANY") {
$sql .= "AND category = $category "; }
if ($subcategory !== "ANY") {
$sql .= "AND subcategory = $subcategory "; }
if ($country !== "ANY") {
$sql .= "AND country = $country "; }
$sql .= "ORDER BY $order $sort LIMIT $limit OFFSET $offset";

Related

pass NULL to php mysql where clause

One of the column in table has been set as NULL, will contain or won't contain value.
Now, if user input is NULL then select all row that contains null. If in case of non-empty input, then select accordingly.
WHERE student.section = NULL // tried like '', 'NULL'
But I found this is not a valid way
So I do following logic, but I thought it is not well-structured, I thought it can be shorten, to prevent repetitive code.
if section is null
if(empty($_POST['section'])){
$result=$con->prepare(
"SELECT
...
FROM student
WHERE student.class=:cid AND student.section IS NULL"
)
$result->bindParam(':cid',$_POST['class']);
$result->execute();
} else {
$result=$con->prepare(
"SELECT
...
FROM student
WHERE student.class=:cid AND student.section=:sid"
)
$result->bindParam(':cid',$_POST['class']);
$result->bindParam(':sid',$_POST['section']);
$result->execute();
}
Remove the superficial table usage. If there are no joins you don't need to put it in again, this will make it "shorter" but keep the same logic.
SELECT
...
FROM student
WHERE class=:cid AND section=:sid
There I saved you about 14 keystrokes and0<14 so it's "reduced".
I know I said IS NOT NULL in the comments but logically there is a difference between
AND student.section=:sid
AND
AND student.section IS NOT NULL
IF student.section = 10 and :sid is 20, you won't get the record, but if you change it to IS NOT NULL then you will because 10 certainly is not null, but it's also not 20, and thus the logic has been changed. In once case you don't get a record in the other you do.
UPDATE
This is the only other thing I can think of
$sql = 'SELECT
...
FROM student
WHERE class=:cid AND section';
if(empty($_POST['section']))
$sql .= ' IS NULL';
else
$sql .= ' = :sid';
$result=$con->prepare($sql);
$result->bindParam(':cid',$_POST['class']); //this is wrong
$result->execute();
UPDATE1
But, you really shouldn't do this either.
$result=$con->prepare($sql); //this is PDOStatment not a result
$result->bindParam(':cid',$_POST['class']); //this is wrong
$result->execute(); //your not setting a result variable
Also it will be hard to conditionally bind to stmt (PDOStatment object) because you don't yet have it when the query is being constructed. You could do prepare 2x and bind to cid 2x. You could do the condition 2x, and then bind in the second condition. But, we are shorting it and fortunately we can pass the arguments in as an array for execute.
So I would change that to use an array of parameters
$sql = 'SELECT
...
FROM student
WHERE class=:cid AND section';
$param = [':cid' => $_POST['class']];
if(empty($_POST['section'])){
$sql .= ' IS NULL';
}else{
$sql .= ' = :sid';
$param[':sid'] = $_POST['section'];
}
$stmt=$con->prepare($sql);
$result = $stmt->execute($param);
$data = $result->fetchAll(PDO::FETCH_ALL);
The way you worded the question made it difficult to understand. This is just basically DRY (Don't Repeat Yourself) principles which is good. Unlike WET (Write Everything Twice) ... lol. So when someone says your coding is all WET you know what they mean now. :)
In fact I was so confused I almost missed the $result issue.
Cheers!
When selecting NULL values you shouldn't use equal statements. You should use IS statements, like so:
For null values
SELECT foo
FROM bar
WHERE status IS NULL;
or for not null values
SELECT foo
FROM bar
WHERE status IS NOT NULL;

Dynamically generated query

I am using mysql to create a search function from a database, however from the way the rest of the program is designed the user must only return 1 result from the info they enter. That is fine for me to program errors and such but I am having trouble accepting multiple strings as inputs to select the data from the table?
How do I make people be able to enter a combination of multiple fields (firstname, phone) etc. and come up with the results that match them without having the empty fields skew the results? i.e(Phone number is blank so only returning people with blank phone numbers)?
SELECT * FROM `users` WHERE `First_Name` = '$_SESSION[queryfname]
At the moment above is what the query is and I am unsure of what function to use (AND, OR) any help would be appreciated. Thanks it advance.
Generally this is something you would handle in your programming language (seems to be PHP here), and only query for the fields you are provided. You could do that like so :
$wheres = array('1=1');
if($_SESSION['queryfname']){
$wheres[] = "`First_Name` = '{$_SESSION['queryfname']}'";
}
if($_SESSION['querypnumber']){
$wheres[] = "`Phone_Number` = '{$_SESSION['querypnumber']}'";
}
$sql = "
SELECT *
FROM `users`
WHERE " . implode($wheres,' AND ');
however if you are limited to doing it in your SQL, you could do something like this
SELECT
*
FROM `users`
WHERE
(
`First_Name` = '{$_SESSION['queryfname']}'
AND
`First_Name != ''
)
OR --Could also be AND
(
`Phone_Number` = '{$_SESSION['querypnumber']}'
AND
`Phone_Number` != ''
)
LIMIT 1
You can try the limit:
SELECT * FROM `users` WHERE `First_Name` = '$_SESSION[queryfname] LIMIT 1;

Select From table results that don't equal to $var?

How do I make it pick all results that are not equal to the $var , here's my code.
$opti=mysql_query("SELECT * FROM table1 WHERE imageid=$image_id");
while ($vari = mysql_fetch_array($opti)) {
$var = $vari['tagid'];
$options=mysql_query("SELECT * FROM table WHERE id!=$var");
while ($taghe1 = mysql_fetch_array($options)) {
$tagname = $taghe1['name'];
echo "".$tagname.", ";
} }
Try:
$options=mysql_query("SELECT * FROM table WHERE id<>{$var}");
You can probably see from the answer you accepted that adding the quotes solved your problem. Another way to do this is to just use one query. I will show an example using mysqli instead of the deprecated mysql, but the same query should work in mysql if you must use it. I added a couple of other suggestions that aren't really addressing your question, but make me feel better about my answer.
// Please be sure to escape $image_id before using it like this
$unused_tags = mysqli_query($db, "SELECT `name` FROM `table` AS t
LEFT JOIN (SELECT tagid FROM table1 WHERE imageid=$image_id) AS t1
ON t.id = t1.tagid WHERE t1.tagid IS NULL;");
while ($tag = mysqli_fetch_array($unused_tags)) {
$tags[] = htmlspecialchars($tag['name']); // escape your output
}
echo implode(", ", $tags); // doing it this way eliminates the trailing comma
You could use this:
$options=mysql_query("SELECT * FROM table WHERE id not in ('$var')");
You could have multiple values here, e.g.
$options=mysql_query("SELECT * FROM table WHERE id not in ('$var1', '$var2', '$var3')");

PHP SQLSRV Sorting with Parameter of Prepared Statement

I can't figure out why sorting will work as long as I'm not using $sort as a passed in parameter. Example below will work for sorting:
$sort = "quantity desc";
$sql = " with items as (
SELECT i.[item_id]
,i.[name]
,i.[value]
,i.[quantity]
,i.[available]
,isnull(r.awarded, 0) as awarded
, ROW_NUMBER() OVER(
ORDER BY $sort
) rowNumber
FROM [Intranet].[dbo].[Goodwell_Item] i
LEFT JOIN (
SELECT r.item_id
, COUNT(1) awarded
from [Intranet].[dbo].[Goodwell_Reward] r
group by r.item_id
) as r
ON i.item_id = r.item_id
)
SELECT *
FROM items
WHERE rowNumber BETWEEN (?) and (?)
and ( (?) = '' OR (available = (?)))
";
$params = array( $pagify['startFrom'], $end, $available, $available );
$stmt = sqlsrv_query( $conn, $sql, $params );
However if I change the line with ORDER BY to:
ORDER BY (?)
and add it to my $params like so:
$params = array($sort, $pagify['startFrom'], $end, $available, $available );
then the sort for some reason is being ignored.
Please tell me how to get the sort working in a way that doesn't allow SQL injection.
I am dealing with this exact issue right now, and cannot find anything online to help.
I have tried:
$query = "SELECT * FROM {$this->view} WHERE SeriesID = ? ORDER BY ? ";
$result = $conn->getData($query, array($seriesID,$sortBy));
and
$query = "SELECT * FROM {$this->view} WHERE SeriesID = ? ORDER BY ? ?";
$result = $conn->getData($query, array($seriesID,$sortBy,$sortOrder));
In both cases, I get no error, and no results.
I think the only way to solve this safely is to use a switch statement before the query to manually validate the acceptable values. However, unless you're only ever dealing with one table, you can't know what the possible values are for the SortBy column.
However, if you just go with the assumption that the values at this point have already been cleaned, you can go with the non-parameterized version like this:
$query = "SELECT * FROM {$this->view} WHERE SeriesID = ? ORDER BY " . $sortBy . " " . $sortOrder;
$result = $conn->getData($query, array($seriesID));
What I plan to do is make sure to validate sortBy and sortOrder before I pass them to the method that contains this code. By doing it this way, each place I call the code becomes responsible for validating the data before sending it. The calling code would know the valid possible values for the table (or view in this case) that it is calling. (I'm the author of both pieces of code in this case, so I know it's safe.)
So, in short, just make sure that the values at this point in the code are already cleaned and safe, and push that responsibility up one level the code that calls this code.

Unknown column 'xyz' in 'where clause'

I created a user defined sql query that doesn't work. Users are supposed to be able to enter search strings in an input field, submit then see the results of their search but everytime I enter a search for something that I know is in the database I get the unknown column "x" in "where clause" error message.
Would you please help me fix the problem? Here's the code that i wrote for it so far...
...
mysql_select_db("mydb", $c);
$search = $_POST['search'];
$rslt = mysql_query("SELECT * FROM mytable
WHERE 'mycolumn' RLIKE $search");
while($row = mysql_fetch_array($rslt))
{
echo $row['myrow'];
echo "<br />";
}
if (!$row)
{
die('uh oh: ' . mysql_error());
}
?>
Change the code to this:
1) Convert quotes to backticks around column name.
2) Surround $search with single qoutes to make it a string.
$rslt = mysql_query("SELECT * FROM mytable WHERE `mycolumn` RLIKE '{$search}'");
This helps for sure
just change the variable $search to be read as a string i.e $search
so it will be like this
$rslt = mysql_query("SELECT * FROM mytable WHERE mycolumn RLIKE '$search'");
I would like to add a few about security and performance.
It is unsafe to put user input (any GET, POST or cookie data) directly into the SQL query. This is a serious security issue called SQL injection. To avoid it, use mysql_real_escape_string() function.
Also, SELECT * FROM mytable ... is not a good practice. It is recommended to explicitly list all the columns needed even if they all are:
SELECT col1, col2, col3, col4, col5 FROM mytable ...

Categories