Reputation: 684
I have a mysql field which may contain single center_id values like AB or csv values like AB,AJ etc..
Currently i do the following in php:
$usercenter = $_SESSION['usercenter'];
$searchForValue = ',';
if( strpos($usercenter, $searchForValue) !== false ) {
$centerid = explode(',', $usercenter);
}
else {
$centerid = $usercenter;
}
and in sql query i do:
SELECT id,node
FROM followup
WHERE center_id IN('".implode("','",$centerid)."')
If there are csv values, it works correctly. How can I write the query to check for both csv values and single value ??
Requesting help..
Upvotes: 0
Views: 1702
Reputation: 26490
While it doesn't use indexed values (so for huge datasets it can be rather slow), you can use the MySQL function FIND_IN_SET()
. This can search for a single value in a comma-separated list.
While this can't search for multiple values at once, from what I understand in the question, you're just looking for a single value at a time.
The function takes the value to search for (case-sensitive!), and then the column to search in.
SELECT id,node
FROM followup
WHERE FIND_IN_SET('AB', center_id)
If its the other way around, and you're looking to use all those values in a WHERE IN (..)
, then you can just explode()
it regardless if it is one or not - the returnvalue will be an array which you can use, it doesn't matter if its 1 or greater length. You should however, use a prepared statement in doing so. You can achieve that by generating a dynamic query based on the length of the array.
MySQLi:
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); // Set MySQLi to throw exceptions - this allows you to automagically check for errors
// Create connection, $mysqli = new mysqli(...);
$parts = explode(',', $usercenter); // Split the comma-separated values
if (empty($parts)) {
// Handle it
}
// Generate dynamic SQL, execute and fetch
$stmt = $mysqli->prepare("SELECT id, node
FROM followup
WHERE center_id IN (".implode(',', array_fill(0, count($parts ), '?')).")");
$stmt->bind_param(str_repeat("s", count($parts)), ...$parts);
$stmt->execute();
$stmt->bind_result($id, $node);
while ($stmt->fetch()) {
// Use $id and $node for each row
}
$stmt->close();
PDO:
// Create connection, $pdo = new PDO(...);
// You should set PDO to throw exceptions on errors
$parts = explode(',', $usercenter); // Split the comma-separated values
if (empty($parts)) {
// Handle it
}
$stmt = $pdo->prepare("SELECT id, node
FROM followup
WHERE center_id IN (".implode(',', array_fill(0, count($parts ), '?')).")");
$stmt->execute([...$parts]);
while ($row = $stmt->fetch()) {
// Use $row['id'] and $row['node'] for each row
}
You might also want to look into filtering out empty values after exploding.
Upvotes: 1
Reputation: 835
You should use FIND_IN_SET() function returns the position of a string within a list of strings. it is working both comma separated and individual values. try the following query
SELECT id,node
FROM followup
WHERE FIND_IN_SET('center_id','".implode("','",$centerid)."')
Upvotes: 1
Reputation: 5061
Given your schema the only solution I can think of is using LIKE
.
SELECT id, node FROM followup WHERE center_id LIKE "%AD%"
;
But this will also select rows with CAD
, ADA
etc. and can only used to check a single option per condition (so you would have to use AND
/OR
with multiple LIKE
statements.)
Also your solution is kind of an antipattern. Normally you would use a one-to-many relation for this.
Upvotes: 1