WHERE IN SQL condition problem - php

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

Related

SQL get an id from a column where ids separated by commas

I have a column named id with a bunch of ids separated by commas like this:
asdaxxdfd2,wwfsfdssdfsd6,sdfdsfdsed2,23445rr55
I need to match an id from the column to an existing $user_id
Trying this didn't do it:
"SELECT id FROM my_table WHERE id LIKE '%" . $user_id . "%'";
Not sure what else I can do.
Thank you.
"SELECT id FROM my_table WHERE concat(',', id, ',') LIKE '%," . $user_id . ",%';"
should do it.
But I also strongly recommend to normalize the schema.
Your question is a little bit ambiguous, I don't know if this solution is what you intends:
SELECT REGEXP_SUBSTR(id, '[^,]+', 1, 1) COLUMN_1,
REGEXP_SUBSTR(id, '[^,]+', 1, 2) COLUMN_2,
FROM my_table;
or just
SELECT id
FROM my_table
WHERE id LIKE '%wwfsfdssdfsd6%'
SELECT REGEXP_SUBSTR(id," . $user_id . ") UserID FROM my_table;
This will return the matching user id but again using a database with values stored in a single row is never a good idea.
SELECT * FROM tbl WHERE id REGEXP "[[:<:]]$user_id[[:>:]]";
Those match "word boundaries", thereby handling beginning and end of string.
But, without normalizing there is no way to make a query that runs faster than a full table scan.

SQL Query to a Column with ID Numbers Separated by Commas?

The Script:
<?php
include("connect.php");
?>
<?php
echo "<h1>The Hashtag: </h1>";
if(isset($_GET['hashtag'])){
echo $_GET['hashtag'];
}
// Select the ID of the given hashtag from the "hashtags" table.
$tqs = "SELECT `id` FROM `hashtags` WHERE `hashtag` = '" . $_GET['hashtag'] . "'";
$tqr = mysqli_query($dbc, $tqs) or die(mysqli_error($dbc));
$row = mysqli_fetch_assoc($tqr);
// This prints e.g.:
// 100
echo "<br/><br/>";
print_r($row['id']);
// Select the threads from the "thread" table which contains the hashtag ID number.
$tqs_two = "SELECT * FROM `thread` WHERE `hashtag_id` IN ('" . $row['id'] . "')";
$tqr_two = mysqli_query($dbc, $tqs_two) or die(mysqli_error($dbc));
$row_two = mysqli_fetch_assoc($tqr_two);
echo "<br/><br/>";
print_r($row_two);
?>
The script should select the rows by that ID number of the hashtag. It should look in the "hashtag_id" column of the table and see if that ID number can be found there, if it can be found there, then it should select that row.
The ID numbers are inside that "hashtag_id" column separated by commas.
Example:
98, 99, 100
Basically, is there a way to do a SQL query to see if the column "contains" that ID number or may have to something else here?
Any suggestions are appreciated.
As Jay says, you can use "contains". You'll need to be cautious though; if you are looking for a hashtag_id of "9", your query needs to avoid returning "19", "99", "93", etc. To that end, you have rely on the exact formatting of the data in that hashtag_id field. If your numbers are really separated by commas and spaces, you can easily find exact matches that ARE NOT AT THE BEGINNING OR END of the query by doing "hashtag_id LIKE '%, 9,'". That won't, however, find any at the beginning or the end of the hashtag_id field. To catch those, you ALSO need "hashtag_id LIKE '9, %'" and "hashtag_id LIKE '%, 9'".
So, to catch all three possibilities:
SELECT * FROM `thread` WHERE `hashtag_id` LIKE '9,%' or `hashtag_id` LIKE '%, 9,%' or `hashtag_id` LIKE '%, 9';
To do contains you would use LIKE -
$tqs_two = "SELECT * FROM `thread` WHERE `hashtag_id` LIKE '%" . $row['id'] . "%'";

SQL select command using string with comma separated IDs

I have a string in PHP like:
"1234,2345,4567,5676,234,12,78957".....
I want to extract these numbers in varchar(30) format and use them on a command like
SELECT * FROM TABLE_NUM WHERE ID LIKE '%NUM';
where NUM will have above mentioned 7 strings.
And if possible i would also like to restrict '%' in '%NUM' to 1-5 characters only i.e. the prefix should not be greater than 5 characters. Example NUM = 1234 and ID has (31234,5678956781234) it should only provide first one as result and not the other one.
Accordingly I will get a merged result of all matching rows.
How can I achieve this ?
Thank You!
If that string is coming from a column somewhere in the database, you should fix the schema. It's almost always a bad idea to design a schema where you have to process sub-columnar data.
If it's a string from outside the database and you just want to run queries based on the individual parts, you're probably better off using facilities outside of your DBMS to construct the queries.
For example, using bash under Linux:
pax> list="1234,2345,4567,5676,234,12,78957"
pax> for i in $(echo $list | sed 's/,/ /g'); do
...> echo mysql "\"SELECT * FROM TABLE_NUM WHERE ID LIKE '%$i'\""
...> done
mysql "SELECT * FROM TABLE_NUM WHERE ID LIKE '%1234'"
mysql "SELECT * FROM TABLE_NUM WHERE ID LIKE '%2345'"
mysql "SELECT * FROM TABLE_NUM WHERE ID LIKE '%4567'"
mysql "SELECT * FROM TABLE_NUM WHERE ID LIKE '%5676'"
mysql "SELECT * FROM TABLE_NUM WHERE ID LIKE '%234'"
mysql "SELECT * FROM TABLE_NUM WHERE ID LIKE '%12'"
mysql "SELECT * FROM TABLE_NUM WHERE ID LIKE '%78957'"
That script will echo the commands to do what you want (assuming mysql is the correct CLI interface to your DBMS) - simply remove the echo at the start to actually execute the commands.
For PHP (as per your question edit), you can use the explode function to split the string, something like:
$list = "1234,2345,4567,5676,234,12,78957";
$numbers = explode (",", $list);
then execute a query for each element of $numbers.
If what you're after is a single result set formed from all of those values, there are other ways to do it. One involves using the list to construct an "uber-query" string that will do all the work for you, then you execute it once.
Simply use an or clause to join the different "sub" queries into one (pseudo-code):
$query = "select * from table_num"
$joiner = " where"
for each $element in $list:
$query = $query + $joiner + "id like '%" + $element + "'"
$joiner = " or"
execute_sql $query
That ends up giving you the query string:
SELECT * FROM TABLE_NUM
WHERE ID LIKE '%1234'
OR ID LIKE '%2345'
:
OR ID LIKE '%78957'

Search Multiple Items in Multiple columns

I have 6 select items in a form. I want to search those 6 in MYSQL DB. I can retrieve results if I use only one, like:
$result = mysql_query("SELECT * FROM wsinmuebles WHERE Property_Type LIKE '%{$_POST['Property_Type']}%'");
But when I try more, I get no results!
$result = mysql_query("SELECT * FROM wsinmuebles WHERE
Property_Type LIKE '%{$_POST['Property_Type']}%' AND
Estado LIKE '%{$_POST['Estado']}%' AND
Ciudad LIKE '%{$_POST['Ciudad']}%' AND
Urbanizacion LIKE '%{$_POST['Urbanizacion']}%' AND
Operacion LIKE '%{$_POST['Operacion']}%' AND
Precio_bsf LIKE '%{$_POST['Precio_bsf']}%'");
This comes from a form by the POST method.
What I need is to look for Property_Type, Estado, Ciudad, Urbanizacion, Operacion and Precio_bsf variables in MYSQL DB, and receive only the results that match all those values.
First, escape the post values using mysql_real_escape_string (Link) to avoid any SQL injection attacks and also issues with the data having ' characters.
Second echo the query and run it against the database and check the table data to see if the
query indeed should return some values or may be there are no matches when include the rest of criteria since you mentioned that you are expecting the results that match all those values.
Dont use And use Or between criteria, and after all you should know that concatenating strings and executing queries is giving possible SQL Injection, that is when instead of your search string I end your query and execute given action, for example "' and 1=1; delete wsinmuebles" if this is my serach query you will lose all your data.
$result = mysql_query("select * from tbl1 where Name='".mysql_escape_string ($_POST["value"]."'" );
If a field, say Urbanizacion is null, your query will not return it.
Urbanizacion LIKE '%%' => FALSE when Urbanizacion is Null
You will need to handle Nulls. I also strongly urge you to protect the code from SQL Injection using mysql_real_escape_string
$result = mysql_query("
SELECT * FROM wsinmuebles WHERE
IFNULL(Property_Type,'') LIKE '" . mysql_real_escape_string($_POST['Property_Type']) ."' AND
IFNULL(Estado,'') LIKE '" . mysql_real_escape_string($_POST['Estado']). "' AND
IFNULL(Ciudad,'') LIKE '" . mysql_real_escape_string($_POST['Ciudad']) ."' AND
IFNULL(Urbanizacion,'') LIKE '" . mysql_real_escape_string($_POST['Urbanizacion']) ."' AND
IFNULL(Operacion,'') LIKE '" . mysql_real_escape_string($_POST['Operacion']) ."' AND
IFNULL(Precio_bsf,'') LIKE '" . mysql_real_escape_string($_POST['Precio_bsf']) ."'");

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

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.

Categories