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

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.

Related

using where statement with a sequence of ids

In my table, I have a column that it has a set of users id. its name is users_id.
each id separated with a comma(,).
ex : users_id = '1,2,3,4,5';
if I passed $id=1 to my function, how can I using where statement ?
function($id){
$sql = "select * from content_noti
where ??????"
}
You can add a leading and a trailing , in the field value in DB.
e.g.
Change
1,2,3,4,5
to
,1,2,3,4,5,
So that every Id has leading and trailing comma ,
Now, update the function body:
function($id){
$sql = "select * from content_noti
where users_id LIKE '%,$id,%'"
}
In this case you don't have any possibility of mistake as if you search user id 1 then you will get only 1 and not 11 or 111 or 1343.
Working Demo
if you have multiple ids than it would be better to use IN with query
$sql = "select * from content_noti where id IN (?)"
if you are looking for reverse than use find_in_set
$sql = "select * from content_noti where FIND_IN_SET(?, id)";
You can use regular expressions in mysql:
function($id){
$sql = "SELECT * FROM content_noti WHERE users_id REGEXP '(^|,)" . $i . "($|,)'";
}
SELECT * from content_noti where users_id = "1" OR users_id = LIKE '%1,%' OR users_id = LIKE '%,1%'
Storing multiple chunks of data as a single comma seperated colum is really poor design for databases and if at all possible you should look into normalizing this by making a coupling table and joining on that.
The performance of the above query will be terrible and it'll be hard to maintain.

MySql - FIND_IN_SET check if all exist

I want to check in mysql if all given keys exists in set or not. like:
$comma_separted_user_ids = "20,2,9,8,31,1";
$query ="SELECT conversation_id FROM message
WHERE FIND_IN_SET($comma_separted_user_ids, user_ids) ";
// data of user_ids = "1,2,8,9,20,31";
I want to check if all user id exist in user_ids column or not, user_ids are not properly ordered.
Please suggest a solution, thanks.
While it is technically feasible:
$query =
'SELECT conversation_id FROM message'
. 'WHERE FIND_IN_SET('
. str_replace(
',',
', user_ids) AND FIND_IN_SET('
$comma_separted_user_ids
)
. ', user_ids)' ;
... you should never do this!
Instead, create a new table to model the many-to-many relationship that exists between your user and message entities (e.g. participant). This is basic normalisation.
Then the query becomes trivial and performant:
SELECT conversation_id FROM participant
WHERE user_id IN ($comma_separted_user_ids)
GROUP BY conversation_id
HAVING COUNT(user_id) = [number of items in $comma_separted_user_ids]
Since you don't know the ordering, I don't see a way around FIND_IN_SET. Like others said, it'd be far better to normalise your table structure.
But in the interest of providing an answer to the question, you'll need to create a list of FIND_IN_SET operators.
// A list of IDs.
$comma_separated_user_ids = "20,2,9,8,31,1";
// The TRUE string will make sure that the array
// always contains at least one item.
$where = array("TRUE");
// Iterate over the IDs and create strings such as
// "FIND_IN_SET(1, column_name_here)"
foreach(explode(",", $comma_separated_user_ids) as $id) {
$where[] = "FIND_IN_SET($id, user_ids)";
}
Then it's a simple matter of joining the strings together:
// Join everything together with AND (&&).
// Since "0" is considered FALSE, this works.
$where = implode(" && ", $where);
// Query for rows.
$query ="SELECT conversation_id FROM message WHERE ($where) ";
Don't use this if you don't need to. It won't scale very well.
You can do this:
SELECT conversation_id
FROM message
WHERE FIND_IN_SET($comma_separted_user_ids, user_ids) > 0
GROUP BY conversation_id
HAVING count(distinct user_id) = 1 + (length($comma_separted_user_id) - length(replace($comma_separted_user_id, ',', '')))
The having clause is counting the number of elements in the comma separated list.
If you are creating the SQL, you should consider using a table to store the values instead of a list. A join approach can take advantage of indexes, which find_in_set() cannot.
i guess you should write it like this :
$comma_separted_user_ids = "20,2,9,8,31,1";
$query ="SELECT conversation_id FROM message
WHERE user_id IN ($comma_separted_user_ids) ";

Fetch string of all id from database using query

Hello i Have tableuser, with column id and many more. now i want all id in string form concatenated with comma separation and appending prefix as A.
means suppose i have records with id 1, 2, 3, 4 etc
now i want result like A1,A2,A3 like this
i did it with my way but its too complex i want to do it with single query.
my code are as under its working fine.
$send_idstring='';
$qry="SELECT concat('A',id) as id FROM `admin` WHERE concat(fname,' ',lname) LIKE '%".addContent($searchVal)."%' ";
$send_id=mysql_query($qry);
while($row=mysql_fetch_assoc($send_id)){
$send_idstring.=$row['id'].',';
}
$send_idstring=trim($send_idstring, ",");
echo $send_idstring;
it gives me output as i want but i want another way to do it please suggest.
Try
SELECT GROUP_CONCAT(CONCAT('A', `id`) SEPARATOR ',') AS idList FROM `admin`;
http://dev.mysql.com/doc/refman/5.5/en/group-by-functions.html#function_group-concat

Get Duplicate data from the Database

i want to fetch duplicate data from the database but the problem is:
i have userids in an array like :
1235, 1235, 5468, 84321, 1235
i used implode and to make that array in string in implement into the database like:
"select * from tbl_name where userid in ('" . $implode_arr . "') limit 0, 10";
which is give me the result like 1235, 5468, 84321 but i want all the data, solution for this is simply run the query in the FOR LOOP or else
but i want same because i add the pagination within the query.
I don't want any code because its already working but the problem is to add pagination Please help to resolve the problem :(
It sounds like you want to join in the user data into this query. You can do that using a LEFT JOIN like this:
SELECT *
FROM tbl_name
LEFT JOIN database_name.user ON database_name.user.id = tbl_name.userid
WHERE userid IN (...)
LIMIT 0, 10
This is assuming your users are stored in the user table in the database_name database, and that the user table has an id field which matches up to the tbl_name field userid. If your fields or table names are different, just change them in this query. In PHP that would be:
"SELECT * FROM tbl_name LEFT JOIN database_name.user ON database_name.user.id = tbl_name.userid WHERE userid IN ('" . $implode_arr . "') LIMIT 0, 10"
Note that to connect two databases, both must be accessible by your same connected user.
Try this it would also work as expected
select * from tbl_name where FIND_IN_SET(user_id,'1235, 1235, 5468, 84321, 1235
') limit 1,10
Check this to remove duplicates

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