Query find value in comma seperated list mysql - php

in my script a "restaurant" can have multiple locations so, i made a column in the restaurant table containing a coma seperated list with locations.
Now i want to make a msql query that checks if the id can be fount is this column (comma seperated list) and if so then select it. i came up with this
SELECT restaurant_id,restaurant_name
FROM restaurant WHERE ('.$locIdList.') IN (locationRes)
ORDER BY restaurant_name ASC'
It does work... but i have some restaurants where I added location 16 and 17 so (16,17) now when i do this query for location 16 it shows the restaurant but when i dot this for location 17 it does not... but the whole point was to get the multi values from the comma seperated list.
So how to do this ?

You can use PHP to generate the query for each comma-delimited value. i.e., run a PHP loop on comma-delimited comparison string, convert it into individual items and compare each item through LIKE Operator and an IN () function.
SELECT restaurant_id,restaurant_name
FROM restaurant WHERE ('16') IN (locationRes)
OR
FROM restaurant WHERE ('17') IN (locationRes)
ORDER BY restaurant_name ASC'

The best solution would be to create a relation table that implements the many-to-many relationship between restaurants and locations. Then you can use a solution like How to return rows that have the same column values in MySql to find all the restaurants that are in all locations.
To search for a value in a comma-separated list, you use FIND_IN_SET. But this can only search for one value at a time. If you want to find restaurants that are in all locations, you need to combine multiple calls:
$locArray = explode(',', $locIdList);
$locQuery = implode(' AND ', array_map(function($loc) { return "FIND_IN_SET($loc, locationRes)"; }, $locArray));
$query = "SELECT restaurant_id,restaurant_name
FROM restaurant
WHERE $locQuery
ORDER BY restaurant_name ASC";
If you want to find restaurants that are in any of the locations instead of all locations, change AND to OR.

You should avoid putting multiple values inside a single column.
Instead, it's recommended to create another table locations(location_id, col1, col2, restaurant_id), while the restaurant_id field references to the primary key in table restaurant.

If you have a comma separated list you are pulling from a database, you could use PHP to separate the list and create an array of each item.
$result_of_sql = "restaurant 1, restaurant 2, restaurant 3, restaurant 4, restaurant 5, restaurant 6";
$restaurants = explode(',', $result_of_sql);
echo '<ul>';
foreach ($restaurants as $restaurant) {
echo '<li>' . trim($restaurant) . '</li>';
}
echo '</ul>';
What happens here is first, you pull out all of you restaurants (the comma separated list). Then you use explode to take away the commas and create an array. Then you use the foreach loop to echo the entire array out. trim is just to clean everything up by removing whitespace you might have before and after the restaurant name.

Related

How to search something in the Database independent of the sequence of words?

I am working on a search filter that connects to a MySQL database. It accepts a keyword parameter; however, it only searches for the keyword in the order it is typed in. For example: If I type in "house rental", it looks for the term in xyz column in the order it is typed it.
However, I would like to change it so that it searches for both those terms are independent of the order they are typed in. Example, if typed in "house rental", the result should contain listings that have either, "house rental" or "rental house" mentioned somewhere in the xyz columns.
I have tried to break the keywords, put it in an array and do a foreach loop on the array to get the result but it generates correct but undesired results. The results that are generated are not the ones that I required.
$samp_text = 'House Rental';
$split_string_array = preg_split('/[\s,]+/', $samp_text);
foreach ($split_string_array as $each_sql_query) {
print_r('SELECT * FROM XYZ WHERE $keyword LINK = %' . $each_sql_query . '% '. "\r");
}
I would like a suggestion on how to tackle this problem.
While the method Sloan Thrasher suggests works, it does not scale.
The solution is to create a table contains each keyword from a searchable document as a single row with a foreign key to the original document with an index on the search word then the foreign key. Split your search term into an equivalent table, join the 2 and count the matches:
Select doc.txt, count(*)
From doc
Inner join keywords
On doc.id=keywords.doc_id
Inner join search
On keywords.word=search.word
Where search.query_id=?
Group by doc.txt
Order by count(*) desc
Alternatively just use the built-in fulltext capability of mysql.
You can build a query that will check for all keywords at once and give you list of rows that contain all of the keywords.
If you want all rows that contain one or more keywords, change the AND in the implode function to OR.
$samp_text = 'House Rental';
$split_string_array = preg_split('/[\s,]+/', $samp_text);
$qstr = "SELECT * FROM XYZ WHERE ";
$keywords = array();
foreach ($split_string_array as $each_sql_query) {
$keywords[] = " LINK = '%" . $each_sql_query . "%'\r")
}
$qstr .= implode(" AND ",$keywords);
// Code to execute query and use results.

How to split row into multiple rows from the MySQL?

I have a MySQL data table, in which I have more than 2 columns. First column has a unique value clinical trial value whereas second column has disease information. There are, in most of the cases, more than 2 disease names in one cell for a single id. I want to spilt those rows which cell contains two or more than two diseases. There is a pattern for searching also, i.e. small character is immediately followed by capital character., e.g. MalariaDengueTuberculosis like this. Suppose for these three diseases there is unique id, it should show like the following:
NCT-ID disease
4534343654 Maleria
4534343654 Dengue
4534343654 Tubercoulsosis
If you want to store one or more data in one String column, you could use JSON data formatting.
It is not very clear to me what you're trying to achieve. Since you're using PHP you can try to read the tables using PDO and print the results. For example:
$sql = 'SELECT diseases FROM diseases_info_table';
foreach($pdo->query($sql) as $row) {
$diseases = preg_split('/(?=[A-Z])/', $row['diseases']);
$sql2 = 'SELECT * FROM diseases WHERE disease_name IN ("' . implode('","', $diseases) . '")';
foreach ($pdo->query($sql2) as $row) {
print $row['NCT-ID '] . "\t";
print $row['disease'] . "\t";
}
}
But this way you're generating a lot of queries. If it is possible for you to rethink the database structure than I would recommend doing that.
To answer your question:
If you insist on multi data in one column you can use php explode:
$diseases = explode("|", $row['disease']); //Changing | to whatever separates your diseases.
$diseases is now an array of your diseases which you can do:
foreach ($diseases as $disease)
{
echo $disease;
}
However
Personally I would normalise your database now before trying to hack around solutions. Use an ID against your table and then have a diseases table to link to it. ie:
Main table
NCT-ID
4534343654
5768788544
3i33i3i078
Disease Table
disease_id nct_id disease
1 4534343654 Broken Wind
2 4534343654 Chronic Nosehair
3 4534343654 Corrugated Ankles
4 5768788544 Discrete Itching
5 3i33i3i078 Gastric Ejections
6 3i33i3i078 Bloaty Head
This allows multiple diseases against one nct-id. disease_id would be the primary key.

Best way to display web content for specific country using mysql

Need a big help from you.
I need an advice from all you good people out there.
I have some contents that i need to display only to few countries.I am okay with getting the user's country with Geoip.i am storing my content in MySQL database with a country_code field.country code can be empty or any single code or group of comma separated values
What i want to do is,
checking country_code and if it is empty, display that content for all users.
if country_code is not empty and only a single value,display content only for the given country_code users.
if country_code is group of comma separated values,display contents for all the comma separated country users.
i have two options for do this
adding data columns for each country separately and display contents
as for example three columns for three countries US,UK,AU and if user's location is US,
$sql=mysql_fetch_array(mysql_query("SELECT * FROM content_table WHERE US=='$country_code'"));
adding country data for single column as country_code and store US,UK,AU and if user's location is US,
$sql=mysql_fetch_array(mysql_query("SELECT * FROM content_table WHERE country_code!=''"));
$pieces = explode(",", $sql['country_code']);
foreach($pieces as $val){
if($country_code=="US")
//display content
}
NOTE:amount of countries may differs according to my needs
what will be the best practice to overcome this,
using different columns to different country make fast search but adding more columns is not good i think
using single column and iterate comma separated values needs more computation
What should i do..??
please advice me on this.. OR do you have any idea better than this..? Thanks
I'd just say - create a countries table
countries
id, code, name
1, UK , United Kingdom
..... and rest of the countries
In your content table just add another column country_id or country_code
Content
id, title, body, country_code
1, some text, more text, 1
then in your sql
just select * from content where country_code = 'UK' or country_id = 1 // depending on which option you go for
OR
create a separate linking table for allowing content for multiple countries
content_country
content_id, country_id
1, 2
1, 1
1, 3
To fetch content your queries use left/right/inner join e.g.
SELECT *
FROM `content` c
LEFT JOIN content_country cc ON cc.content_id = c.id
AND cc.country_id
IN ( 2, 4 )
$sql=mysql_fetch_array(mysql_query("SELECT *
FROM content_table
WHERE country_code = ''
OR country_code REGEXP ',?". $user_country_code .",?'"));
If I understood you well, you want to show elements to the user only if the user country code is in the country_code field or if the country_code is not specified ?
This should do it, even if a database solution would be better.
Try It:
$sql=mysql_fetch_array(mysql_query("SELECT * FROM content_table WHERE country_code!=''"));
$pieces = explode(",", $sql['country_code']);
# No Need to run loop
#foreach($pieces as $val)
#{
# if($country_code=="US") //display content
#}
if(!empty($pieces)) //
{
if(in_array($user_country_code,$pieces ))
{
echo "display content";
}
}
else
{
echo "display content"; // for all country
}
Use in_array() except of loop. I guess you will use in on user login so you will have user_country_code.

Update MYSQL and SET particular row Content

I am trying to update my table t1 which has rows as following :-
id
menu
Currently i am having data in it as
id = "1"
menu = "menu1 ,menu2 ,menu3, menu4"
I am using explode method of PHP to get MENU row of my table t1.
$show_data = mysql_query("SELECT menu FROM t1");
$showrow = mysql_fetch_assoc($show_data);
$showmenu = $showrow['menu'];
$pieces = explode(",", $showmenu);
Now I want to delete content menu3 from row MENU ,
Please provide me which query should i use , UPDATE , ALTER or DELETE.
You should store your menus in a separate table, linked to this one by a unique identifier.
Then edit that table in the usual way.
It is better to separate $menu1 $manu2 $menu3 and $menu4
You can implode() them as a single $string with \t separator
and Insert it to Mysql.
When nessesary,select the field from table
explode() it to separate strings using \t separator
remove the $menu3 variable frome being imploded this time
again implode() them
and UPDATE the field

Select unique text from an array

I am having a problem selecting the unique text from database.
This is for a movie database, Let's assume I have 2 movies in the database.
1st movie is in category: Drama, Romance, War
2nd movie is in category: Drama, Thriller
What I need, is to return an array wich will display me: Drama, Romance, War, Thriller.
My current query to mysql is the following:
$query = 'SELECT genres FROM imdb WHERE actors LIKE "%%'.$name.'%"';
In an while loop I use "foreach", like this:
foreach(explode(', ', $TMPL['genres']) as $v)
$TMPL['genre'] .= '<option value="'.urlencode($v).'">'.($v).'</option>';
This is returning me all the values, including the duplicated one, like this: Drama, Romance, WarDrama,Thriller
Any clue how to sort this out?
$query = 'SELECT DISTINCT genres FROM imdb WHERE actors LIKE "%%'.$name.'%"';
would do it
just use the array_unique function on that array of your with duplicate values!
$unique_values = array_unique($TMPL['genre']);
use DISTINCT
$query = 'SELECT DISTINCT genres FROM imdb WHERE actors LIKE "%%'.$name.'%"';
So you have a column with a delimited list of genres?
Loop through every row in your query and explode the genres, add every genre to a master array and then use array_unique()
If i understand you correctly you wont be able to do it (easily) with MySQL as you haven't normalised your database properly.

Categories