Check if comma separated value exists in Database with PHP - php

I need to check if my comma separated value exists in Database. And my database also storing in comma separated.
My string is saved as "1,2,3,4,5" in database.
My search string is $bloggerscat = "2,5"
I have tried
(B.category_id LIKE ('%,$bloggerscat') OR B.category_id LIKE ('%$bloggerscat,%') OR B.category_id = '".$bloggerscat."')
Not getting proper result. Please help me.
Advanced thanks...

You can do something like this,
$bloggerscat = '2,5'; // Your input here (string)
$set = explode(',',$bloggerscat); // get the numbers in $set array
$query = 'SELECT * FROM `table` WHERE '; // construct query
foreach ($set as $search)
{
$query .= "FIND_IN_SET($search, column_name) OR "; // append every time for set
}
$query = rtrim($query, ' OR'); // remove last OR
echo $query; // test
Will produce
SELECT * FROM `table` WHERE FIND_IN_SET(2, column_name) OR FIND_IN_SET(5, column_name)
Will give you results from column column_name where comma separated sets have value either 2 or 5.

You have to store the string as ",1,2,3,4,5," in database
then try this code
$currStr = "2,5";
$explCurrStr = explode(",",$currStr);
foreach($explCurrStr as $key=>$all){
if($key==0){
$sql.=" B.category_id LIKE ('%,".$all.",') ";
}else{
$sql.=" OR B.category_id LIKE ('%,".$all.",') ";
}
}

Related

PHP/SQL: Faster Way to Combine Query Results

I'm joining data from two SQL queries and I'm wondering if there is a faster way to do this as a single SQL query because there is a lot of looping involved. I've got two queries that look for different string values in the "option_name" field:
$sql01= "SELECT user_id, option_value FROM wp_wlm_user_options WHERE option_name = 'wpm_login_date' ORDER BY user_id";
$sql02 = "SELECT user_id, option_value FROM wp_wlm_user_options WHERE option_name ='stripe_cust_id' ORDER BY user_id ";
Then I create two arrays:
//Process the 1st SQL query data into an Array
$result_array01 = array();
$j = 0;
while($r = mysql_fetch_assoc($result01)) {
if(!empty($r['option_value'])){
//User Id and Last Login
$result_array01[$j]['user_id'] = $r['user_id'];
$result_array01[$j]['last_login'] = $r['option_value'];
$j++;
}
}
//Process the 2nd SQL query data into an Array
$result_array02 = array();
$k = 0;
while($s = mysql_fetch_assoc($result02)) {
if(!empty($s['option_value'])){
//User Id and Stripe Customer Id
$result_array02[$k]['user_id'] = $s['user_id'];
$result_array02[$k]['cust_id'] = $s['option_value'];
$k++;
}
}
And finally, I combine the arrays:
//Combine the SQL query data in single Array
$combined_array = array();
$l = 0;
foreach($result_array01 as $arr01){
// Check type
if (is_array($arr01)) {
//mgc_account_print("hello: " . $arr01['user_id'] . "\r\n");
foreach($result_array02 as $arr02){
// Check type
if (is_array($arr02)) {
//Check if User Id matches
if($arr01['user_id'] == $arr02['user_id']){
//Create Array with User Id, Cust Id and Last Login
$combined_array[$l]['user_id'] = $arr01['user_id'];
$combined_array[$l]['last_login'] = $arr01['last_login'];
$combined_array[$l]['cust_id'] = $arr02['cust_id'];
$l++;
}
}
}
}
}
Why you doing in two different queries?
Use mysql IN('val', 'val2');
$sql01= "SELECT tbl1.user_id, tbl1.option_value FROM wp_wlm_user_options as tbl1 WHERE tbl1.option_name = 'wpm_login_date'
union all
SELECT tbl2.user_id, tbl2.option_value FROM wp_wlm_user_options as tbl2. WHERE tbl2.option_name ='stripe_cust_id' ";
But using OR/AND will your help you in your case , I didnt see at first that you want combined same table. I didnt delete my answer to help you for another solution
Also you should use DISTINCT to avoid multiple records.
SELECT DISTINCT USER_ID, OPTION VALUE FROM TABLE

How to create multiple word search? SQL

We have made a search field where you can search for ingredients and find recipes.
For now you can only type in 1 ingredient:
if (isset($_POST['search'])) {
$searchquery = $_POST['search'];
$query = mysql_query("SELECT * FROM opskrifter WHERE id IN
(SELECT opskrifterid FROM ingredienser WHERE ing_name IN ('$searchquery'))") or die("search failed");
We want to be able to search for multiple ingredients in the same search field by seperating the ingredients with a "," or something like this.
Is there a simple way to make that happen ?
EDIT:
We tried to use explode like this without succes.
$searchTerms = explode(' ', $searchquery);
$searchTermBits = array();
foreach ($searchTerms as $term) {
if (!empty($term)) {
$searchTermBits[] = "ing_name '$term'";
}}
...
$result = mysql_query("SELECT * FROM opskrifter WHERE id IN (SELECT * FROM WHERE ".implode(' AND ', $searchTermBits)));
Thanks! :)
You could simply get the user to type in his values comma-separated, the the input would be almost in the right syntax for the query. You just have to add semicolons around the values because you search for a string in your table.
You can use PHP's str_replace()-Function:
$vals = $_POST['search'];
$valsFormatted = "'" . str_replace(",", "','", $vals) . "'";
In this code, you replace all the commas of the input with the comma plus semicolons before and behind them in orderto wrap all values of the input with semicolons. You also have to add one at the beginning and at the end of the string. Replace the first comma in the function above with the char you want your users to separate the values with.
After that, you can simply change your query to the following:
$query = "SELECT * FROM opskrifter WHERE id IN
(SELECT opskrifterid FROM ingredienser WHERE ing_name IN ('$valsFormatted'))";
Please also be informed, that your code like this is vulnerable for SQL Injections! Check out this link to learn how to prevent this.
A simple statement like this would work:
$array = implode("','",explode($_POST['search'], ","));
$query = mysql_query("SELECT * FROM opskrifter WHERE id IN (SELECT opskrifterid FROM ingredienser WHERE ing_name IN ({$array}))") or die("search failed");
First explode your search, then implode it (might not even need to do so). After that make sure the array gets used as the 'in' operator as a string/array.
For more information about this, you could read this question: PHP/MySQL using an array in WHERE clause
The working copy from my local machine was this;
$_POST['search'] = "0, 1, 2";
$array = implode ( "','", explode ( ",", $_POST['search'] ) );
$query = mysql_query("SELECT * FROM users WHERE id IN ('$array')") or die(mysql_error());
var_dump ( $array );
var_dump ( $query );
var_dump ( "SELECT * FROM users WHERE id IN ('$array')" );
var_dump ( mysql_fetch_array ( $query ) );
which actually did return users, so if we would take this example and change it to your code, it would be (the query, at least):
$query = mysql_query("SELECT * FROM opskrifter WHERE id IN (SELECT opskrifterid FROM ingredienser WHERE ing_name IN ('$array'))") or die(mysql_error());
Do take note of the changed $array variable too.
First you need to convert the text coming from the search field to array with:
$string = $_POST['search'];
$array = explode( '"' , $string);
So if you put in the search: test"hello"hi
the array will be:
1 => test,
2 => hello,
3 => hi
After that, you need to use the SQL format:
WHERE column_name IN (value1,value2,...)
So you need to change the array we have created to a string with this format:
$string = implode(',',$array);
So the echo of $string will be:
test,hello,hi
and SQL will be :
WHERE column_name IN ($string)

Query a column containing Comma Separated String

I am having an issue with an sql query. Basically I have this method:
public function loadByDirectoryContact($directoryContact,$type='')
{
global $db;
$t = 'directoryprogramme';
$query = 'SELECT c.* FROM `'.$t.'` c ';
$query .= 'WHERE `c`.`presenters` = '.$directoryContact->getId().' ';
$query .= 'OR `c`.`staff` = '.$directoryContact->getId().' ';
if($type!=""){
$query .=" AND c.type='".$type."' ";
}
$query .= QueryBuilder::orderBy('name','asc');
echo $query; die();
$db->query($query,$t);
while($db->next($t))
{
$node = new Programme();
$node->setId($db->get('id',$t));
$node->setName($db->get('name',$t));
$node->setBroadcastTime($db->get('broadcast_time',$t));
$node->setDescription($db->get('description',$t));
$node->setDays($db->get('days',$t));
$node->setSubjects($db->get('subjects', $t));
$node->setStaff($db->get('staff',$t));
$node->setPresenters($db->get('presenters',$t));
$directoryCompany = new DirectoryCompany($db->get('directorycompany_id',$t));
$node->setDirectoryCompany($directoryCompany);
$node->setContributors($directoryContact);
$node->setType($db->get('type',$t));
$this->nodes->add($node);
}
}
It creates a query like this:
SELECT c.*
FROM `directoryprogramme` c
WHERE `c`.`presenters` = 1234
OR `c`.`staff` = 1234
ORDER BY `name` ASC
The problem is that the presenters column stores comma seperated values so in reality it looks like this
presenters
1234,7738,5097,5100
and so for any query where the c.presenters equals any value that is not first in this column it returns no results. I am wondering if there is a way I can query so that it checks the entire String?
You can use the function FIND_IN_SET to find your value in the list:
SELECT c.*
FROM `directoryprogramme` c
WHERE FIND_IN_SET('1234',`c`.`presenters`) > 0
OR `c`.`staff` = 1234
ORDER BY `name` ASC
Remark
Consider normalizing your table design, if you can. This means a separate table for the presenters ids with one row per id.
You can also try:
SELECT c.* FROM `directoryprogramme` c WHERE `c`.`presenters` LIKE '%1234%' OR `c`.`staff` = 1234 ORDER BY `name` ASC
I believe the presenters column is in varchar.

Search query and ordering by matches with my sql

Hi am currently stuck here, been doing research on how to write a mysql statement for a flexible search for products and order them by relevance on a project am working on have seen a few but wasn't helpful please i need help on how to make it work, my current method doesn't work, here it is.
User types in search field and submits "iPad 3rd Generation".
My script breaks the string into words like so.
$termsExploded = array_unique(explode(' ', $term));
No i use php to create an sql query based on the number of words found.
$i = 0;
foreach ($termsExploded as $word) {
if (strlen($word)>1) {
if ($i == 0) {
$where_query = $where_query." name LIKE '%".$word."%'";
}
else{
$where_query = $where_query." OR name LIKE '%".$word."%'";
}
$i++;
}
}
The where query variable now looks like this.
name Like '%ipad%' Or name Like '%3rd%' Or name Like '%Generation%'
Now search for the products ids like so.
$IDs = "SELECT DISTINCT id FROM store_items WHERE".$where_query;
I now create a second where query based on the IDs returned like so
$where_query_s = null;
$i = 0;
foreach ($IDs as $result) {
$returnID = $result->id;
if ($i == 0) {
$where_query_s = $where_query_s." id = ".$returnID."";
}
else{
$where_query_s = $where_query_s." OR id = ".$returnID."";
}
$i++;
};
Now i select the products again based on the distinct IDs returned like so
$items = "SELECT * FROM store_items WHERE".$where_query_s;
Now this works to get the products but how can i sort it based on best match?
Assuming you want to order by the number of matches then build up another string as follows:-
ORDER BY IF(name Like '%ipad%', 1, 0) + IF(name Like '%3rd%', 1, 0) + IF(name Like '%Generation%', 1, 0) DESC
But this will be slow, and takes no account of indexing to improve performance nor of plural / singular (ie, it someone searches for 'flies' it won't rank 'fly' properly).
To put that more into code:-
$where_query = array();
$order_query = array();
foreach ($termsExploded as $word)
{
if (strlen($word)>1)
{
$where_query[] = " name LIKE '%".$word."%'"
$order_query[] = " IF(name Like '%".$word."%', 1, 0)"
}
}
$IDs = "SELECT DISTINCT id FROM store_items WHERE ".implode(' OR ', $where_query)." ORDER BY ".implode(' + ', $order_query)." DESC";
Arrange for your query to look like this:
select field1, field2, etc, count(*) records
from store_items
where blah blah blah
group by field1, field2, etc
order by records desc
If the table is MyISAM based or if it is InnoDB and the version is Mysql 5.6 or greater, then you can use full text search (see http://dev.mysql.com/doc/refman/5.6/en/fulltext-search.html)
effectively you want a query similar to
SELECT * FROM store_items WHERE MATCH (name) AGAINST ('iPad 3rd Generation')
ORDER BY MATCH (name) AGAINST ('iPad 3rd Generation')

WHERE id=(array)

The code below only outputs single line(there are 2 in database that should be outputed).
I think that problem is in id=$data[id] since data1 is array instead of single value.I hoped that while will fix that but it doesnt look too good...
$results1 = mysql_query("SELECT * FROM keywords WHERE keyword='$search' ORDER BY (relevant-irrelevant) DESC");
$data1=mysql_fetch_array($results1);
$results2=mysql_query("SELECT * FROM searchengine WHERE id='$data1[id]'");
while($data2=mysql_fetch_array($results2))
First, isolate your ids, looping to get all of the results:
$ids = array();
while ( $data1 = mysql_fetch_array($results1) ) {
$ids[] = $data1['id'];
}
Then, convert your $ids array into a string. An easy way to do this is via implode():
$results2=mysql_query(
"SELECT * FROM searchengine WHERE id IN (" . implode(',', $ids) . ")"
);
Maybe I´m missing something, but how can $data1['id'] be an array? it´s probably an integer and perhaps a string, but it's not an array. $data1['id'] is a single value; the value of field id in the keywords table
I think you just need to put curly quotes around the variable:
$results2=mysql_query("SELECT * FROM searchengine WHERE id='{$data1[id]}'");
or even better:
$results2=mysql_query("SELECT * FROM searchengine WHERE id=" . (int) $data1['id']);
If id is an integer that is.
And of course if the first query returns more than 1 result, you will have to loop through them as well.
Couldn't you just select the entire thing in one query?
SELECT *
FROM keywords k
searchengine s
WHERE k.keyword='$search'
AND k.id = s.id
$results1 = mysql_query("SELECT * FROM keywords WHERE keyword='$search' ORDER BY (relevant-irrelevant) DESC");
$data1=mysql_fetch_array($results1);
//VERY DANGEROUS TO USE USER INPUT
$in = join(',',$data1['id']);
$results2=mysql_query("SELECT * FROM searchengine WHERE id IN ({$in})");
while($data2=mysql_fetch_array($results2))
You can't pass array as condition. You should:
a. do a for(each) loop in the $data1 array and perform next actions
b. implode the array and search with IN. Example:
$commaSeparated = implode(",", $data1);
$results2=mysql_query('SELECT * FROM searchengine WHERE id IN ('.$commaSeparated.'));
mads.ohm is correct about combining the two queries into a single query.
As for your problem with only getting one return value, your while loop is just overwriting the contents of $data2 each time through.
You could write something like this instead:
$i = 0;
$data2 = array();
while ($row = mysql_fetch_array($results2)) {
$data2[$i] = $row;
$i++;
}
In this case, $data2 is declared as an array, and each iteration of the while loop adds a row from the database to the array.

Categories