MySQL - How to select rows where value is in array? - php

Ok, normally I know you would do something like this if you knew the array values (1,2,3 in this case):
SELECT * WHERE id IN (1,2,3)
But I don't know the array value, I just know the value I want to find is 'stored' in the array:
SELECT * WHERE 3 IN (ids) // Where 'ids' is an array of values 1,2,3
Which doesn't work. Is there another way to do this?

Use the FIND_IN_SET function:
SELECT t.*
FROM YOUR_TABLE t
WHERE FIND_IN_SET(3, t.ids) > 0

By the time the query gets to SQL you have to have already expanded the list. The easy way of doing this, if you're using IDs from some internal, trusted data source, where you can be 100% certain they're integers (e.g., if you selected them from your database earlier) is this:
$sql = 'SELECT * WHERE id IN (' . implode(',', $ids) . ')';
If your data are coming from the user, though, you'll need to ensure you're getting only integer values, perhaps most easily like so:
$sql = 'SELECT * WHERE id IN (' . implode(',', array_map('intval', $ids)) . ')';

If the array element is not integer you can use something like below :
$skus = array('LDRES10','LDRES12','LDRES11'); //sample data
if(!empty($skus)){
$sql = "SELECT * FROM `products` WHERE `prodCode` IN ('" . implode("','", $skus) . "') "
}

If you use the FIND_IN_SET function:
FIND_IN_SET(a, columnname) yields all the records that have "a" in them, alone or with others
AND
FIND_IN_SET(columnname, a) yields only the records that have "a" in them alone, NOT the ones with the others
So if record1 is (a,b,c) and record2 is (a)
FIND_IN_SET(columnname, a) yields only record2 whereas FIND_IN_SET(a, columnname) yields both records.

Related

How can I get all rows with existing value of column in array [duplicate]

If I have an array of say, some ID's of users. How could i do something like this:
$array = array(1,40,20,55,29,48);
$sql = "SELECT * FROM `myTable` WHERE `myField`='$array'";
Is there a simple way to do this, I thought about looping through array items and then building up one big "WHERE -- OR -- OR -- OR" statement but i thought that might be a bit slow for large arrays.
Use IN:
$sql = "SELECT * FROM `myTable` WHERE `myField` IN (1,40,20,55,29,48)";
you can use implode(",", $array) to get the list together from the array.
You want to use IN:
WHERE `myfield` IN (1,40,20,55,29,48)
Use implode to construct the string:
$sql = "SELECT * FROM `myTable` WHERE `myField` IN (" . implode(',', $array) . ")";

Querying WHERE column is IN ($array) returns only one row

I'm trying to query all results where surveyid contains my array $subscibearray. The problem is the SQL query is only returning the first result (44 in this case) instead of all of them. I tried using mysql_fetch_array as well without any success. My results are being outputted via Table. Any help would be appreciated. I omitted as much code as possible to make this easy to read.
Array format:
$subscribearray = "" . join(', ',$subscribearray) . "";
var_dump of $subscribearray:
string(17) "'44, 35, 194, 36'"
query:
$result = mysql_query("SELECT *
FROM surveys
WHERE surveyid IN ($subscribearray)
ORDER BY peercompletetime DESC
LIMIT 100")
or die(mysql_error());
You should:
$subscribearray = join(',', $subscribearray); // 1,2,3
Or:
$subscribearray = "'" . join("','", $subscribearray) . "'"; // '1','2','3'
If you wrap all ids with a string, it will look for the string, and not separated values. ('1,2,3')
Of course, if it's a numeric column you should use the first one.

Select from table where value does not exist

I have a table (country_table) with a list of all countries and their respective ids.
|country_id|country_name|
|ES |Spain |
.
.
.
I have an array, fetched from another table using fetch_array that looks like this:
$array = Array(
[0]=>Array([country_id]=>'ES')
[1]=>Array([country_id]=>'DE')
[2]=>Array([country_id]=>'GB'))
How can I select the records (country_id and country_name) from country_table that do not exist in the table but exist in the array?
$sql ="SELECT country_id, country_name FROM country_table
WHERE country_id NOT IN (". implode(",", $array) .")";
implode() function will generate comma-seprated string representation of array elements .
This is the sql.
select country_id, country_name from table where country_id not in ('ES','DE','GB');
// gather unwanted id's first
$notInIds = array();
foreach ($array as $arr) $notInIds[] = $arr['country_id'];
// prepare query
$query = 'SELECT `country_id`, `country_name` FROM `your_table`
WHERE `country_id` NOT IN (' . implode(',',$notInIds) . ')';
// then execute it
For the question: "How can I select the records (country_id and country_name) from country_table that do not exist in the table but exist in the array?"
I guess you have to write some code (eg. in PHP) in order to achieve the result you want.
The problem is that you can not display data that is not in the table (eg. country_name), that's not possible as you don't know this data. The only possibility would to show the country_id's which are in the array and not in the table as this is the only data you have...

How to use php array with sql IN operator? [duplicate]

This question already has answers here:
Passing an array to a query using a WHERE clause
(17 answers)
Closed 11 months ago.
I have and array with two values and I want to use it with sql IN operator in select query.
Here is the structure of my table
id comp_id
1 2
2 3
3 1
I have an array $arr which have two values Array ( [0] => 1 [1] => 2 )
I want to fetch the record of comp_id 1 and comp_id 2. So I wrote the following query.
SELECT * from table Where comp_id IN ($arr)
But it does not return the results.
Since you have plain integers, you can simply join them with commas:
$sql = "SELECT * FROM table WHERE comp_id IN (" . implode(',', $arr) . ")";
If working with with strings, particularly untrusted input:
$sql = "SELECT * FROM table WHERE comp_id IN ('"
. implode("','", array_map('mysql_real_escape_string', $arr))
. "')";
Note this does not cope with values such as NULL (will be saved as empty string), and will add quotes blindly around numeric values, which does not work if using strict mysql mode.
mysql_real_escape_string is the function from the original mysql driver extension, if using a more recent driver like mysqli, use mysqli_real_escape_string instead.
However, if you just want to work with untrusted numbers, you can use intval or floatval to sanitise the input:
$sql = "SELECT * FROM table WHERE comp_id IN (" . implode(",", array_map('intval', $arr)) . ")";
you need to convert the array into comma-separated string:
$condition = implode(', ', $arr);
And, additionally, you might want to escape the values first (if you are unsure about the input):
$condition = implode(', ', array_map('mysql_real_escape_string', $arr));
$arr is a php array, to the sql server you need to send a string that will be parsed
you need to turn your array in a list like 1, 2, etc..
to do this you can use the function http://php.net/implode
so before running the query try
$arr = implode ( ', ', $arr);
You need to implode your array with ',' comma
$imploded_arr = implode(',', $arr);
SELECT * from table Where comp_id IN ($imploded_arr)
you can only pass string to mysql as query, so try this
mysql_query("SELECT * FROM table WHERE comp_id IN (".implode(',',$arr).")");
All the people here are proposing the same thing but i got a warning in WordPress because of a simple error. You need to add commas to your imploded string. To be precise something like this.
$query = "SELECT *FROM table Where comp_id IN ( '" . implode( "', '", $sanitized_brands ) . "' )";
Hoping it helps someone like me. :)
You're mixing PHP and SQL - for the IN SQL operator, you need a format like:
SELECT * from table WHERE comp_id IN (1,2)
So to get that in PHP you need to do something like:
$sql = "SELECT * from table Where comp_id IN (".implode(',',$arr).")"
Bear in mind that this only works if the array comprises of integers. You have to escape each element if they are strings.
You need something like:
$sql = "SELECT * from table where comp_id in (".implode(',',$arr.")";
You need to actually convert your $arr to a string. The simplest way with what you're doing would be to use implode()
$query = 'SELECT * from table Where comp_id IN (' . implode(',', $arr) . ')';
Right now if you echo your query you'll see that rather than the array being in the IN statement, it will just be the word "Array"
You need to convert the array to a string for use in the query:
$list = implode(',', $arr);
Then it can be used in the IN clause:
SELECT * from table Where comp_id IN ($list)
As per #barryhunter 's answer which works only on array that contains integer only:
$sql = "SELECT * from table Where comp_id IN (".implode(',',$arr).")";
I've made some tweaks to make it work for array of strings:
$sql = "SELECT * from table Where comp_id IN ('".implode("','",$arr)."')";
There are some risks of SQL injection in a few of the previous answers. It might be fine if you are completely certain about $arr being sanitized (and will stay that way). But if you aren't completely sure, you might want to mitigate such risk using $stmt->bindValue. Here is one way of doing it:
# PHP
$in_list = array();
for ($i = 0; $i < count($arr); $i++) {
$key = 'in_param_' . i;
$in_list[':' . $key] = array('id' => $arr[$i], 'param' => $key);
}
$keys = implode(', ', array_keys($in_list));
// Your SQL ...
$sql = "SELECT * FROM table where id IN ($keys)";
foreach ($in_list as $item) {
$stmt->bindValue($item['param'], $item['id'], PDO::PARAM_INT);
}
$stmt = $this->getConnection()->prepare($sql)->execute();
If your array is of Integers :
$searchStringVar = implode(",",$nameIntAryVar);
$query="SELECT * from table NameTbl WHERE idCol='$idVar' AND comp_id IN ($searchStringVar)";
If your array is of Strings :
$searchStringVar = implode("','",$nameStringAryVar);
$query="SELECT * from table NameTbl WHERE idCol='$idVar' AND comp_id IN ('$searchStringVar')";

WHERE IN SQL condition problem

I have this query:
"SELECT * FROM informations WHERE ". $id ." IN (ids)"
It only works if $id is the first value from ids... in ids values are "1,2,3,4,5".
Is there a way for it to work with the rest of the ids?
Would this work for you?
"SELECT *
FROM Informations
WHERE ids LIKE \"" . $id . ", %\" -- try to match against the first value in ids
OR ids LIKE \"%," . $id . ",%\" -- try to match against a value in ids that is neither the first nor the last value
OR ids LIKE \"%," .$id . "\" -- try to match against the last value found in ids"
If ids is a field containing comma-delimited values, then your query is like:
SELECT * FROM `informations` WHERE 3 IN ("1,2,3,4,5")
Instead of what it should be:
SELECT * FROM `informations` WHERE 3 IN (1,2,3,4,5)
There is no automatic tokenisation (splitting on ,) performed; the one value of ids is not automatically converted into a list for you such that IN can work.
Unfortunately your table design has been your undoing here. Can you split the IDs into a separate table using the principle of database normalisation?
Then your query might look like:
SELECT * FROM `informations` WHERE 3 IN (
SELECT `id`
FROM `ids`
WHERE `informations`.`id` = `ids`.`information_id`
)
BTW, "information" is a non-countable noun and, as such, "informations" is wrong.
Update (thanks for the idea, a1ex07!)
Although this is hackery and I still suggest fixing your table layout, I'll be kind and suggest a quick fix.
Willempie was close with:
$query = 'SELECT *
FROM `informations`
WHERE `ids` LIKE "%' . $id . '%"';
Unfortunately, a wildcard match isn't quite powerful enough. Consider if ids is like "1,6,9,12,35,4" and $id is like 3. You get a false positive. The LIKE statement needs to be aware of the commas.
You can add multiple cases:
$query = 'SELECT *
FROM `informations`
WHERE `ids` LIKE "%,' . $id . ',%"
OR `ids` LIKE "%,' . $id . '"
OR `ids` LIKE "' . $id . ',%"';
Or, for brevity, you can work around this with regular expressions:
$query = 'SELECT *
FROM `informations`
WHERE `ids` REGEXP "(^|,)' . $id . '(,|$)"';
For any $id you wish to find, before it must be the start of ids (^) or a comma; after it must be a comma or the end of ids ($). This ensures that $id must be found as a whole, comma-delimited token.
It's a little like "Whole Word Only" in word processor searches, but with commas separating "words" instead of spaces.
Update 2
Another way uses FIND_IN_SET, which performs a search within a comma-delimited string:
$query = 'SELECT *
FROM `informations`
WHERE FIND_IN_SET("' . $id . '", `ids`)';
Your query is technically correct but the values for 'ids' are not.
You should enclose the values of ids within single quotes. If I were to write the code without using ids, it would be like this:
"SELECT * FROM informations WHERE ". $id ." IN ('1','2','3','4','5')"
More info on this rule here: http://dev.mysql.com/doc/refman/5.1/en/comparison-operators.html#function_in
I'm not sure what you are trying to achieve. If ids is a column in informations your code is just a weird way to express "SELECT * FROM informations WHERE ids = ". $id "; If it is a string, I don't see why you need WHERE at all : expression $id in (1,2,3,4,5) is constant, it doesn't require interaction with database; in any case you either grab all rows from informations or none.
UPDATE
Another suggestion :maybe ids is a string field in informations that contains "1,2,3,4,5". In this case you cannot get expected results by using WHERE ... IN. You need to use REGEXP to check if string contains your number.
It has to be column name then IN (comma separated values here).
SELECT column_name(s)
FROM table_name
WHERE column_name IN (value1,value2,...)
You did an error in sql syntax.
This is the correct syntax
"SELECT * FROM informations WHERE ids IN (". $id .")";

Categories