Search comma delimited values in the Database with SELECT MYSQL query - php

I have an issue of getting results from the database. I have a column called "Regions" which as a value contains all the regions user had chosen via newsletter signup form with commas i.e "Middle East, Europe"
I am creating a filter which will need to get all the users list who signup for a particular or multiple regions. Users can select multiple regions. From the frontend am getting all the selected regions in this format "Global,Middle East" which i need to use in my SQL query to find all the users who has the Global and Middle East as a chosen region.
I tried to use FIND_IN_SET but it is not really helping. Tried the below
$trimmedRegions = rtrim($sortType,', ');
$query = "SELECT * FROM health_alerts_subscribers
WHERE FIND_IN_SET(Regions, $trimmedRegions)";
Any ideas how I can achieve the needed result please?

I recommend what user3783243 is saying. I would go with FIND_IN_SET. Here is an example.
SELECT {columns} FROM {table} WHERE FIND_IN_SET({item_to_search}, {comma-delimited column})
A better way would be to create a regions table and add your regions, and then create a related table called, regionsRelated (example) and then add an id from region and the linking table (as a many to many)
Table structure example
Table region
id,region
1, Middle East
2, Global
Table user
id,name
1, John
2, Jan
Table userRegion
userId,regionId
1,1
2,1
SELECT user.id,user.name,region.region from user
left join userRegion ON region.userId=user.id
left join region
where region.region in('Middle East','Global');
In your drop down list just select all regions and when the user selects the ones they want then you would store it in the userRegion table with INSERT INTO userRegion (userid,regionId) (1,2); and so on.

You pretty much need to format your sql like this:
SELECT
*
FROM
table
WHERE
regions = 'Europe' or
regions like 'Europe,%' or
regions like '%,Europe' or
regions like '%,Europe,%' or
regions = 'Middle East' or
regions like 'Middle East,%' or
regions like '%,Middle East' or
regions like '%,Middle East,%'
In PHP you will need to loop through the regions which the user has selected and dynamically build a query like this.

I can suggest this approach.
SELECT * FROM table
WHERE
region like("%Global%")
and region like ("%Middle East%")
In this way you can get the people subscribe to both of them. You can tweak it for your needs, obviously is not going to be the best solution, but you can use it to create a pivot table in case you want to update you db structure.

There is not exact function for your requirement but you can use below code:
$trimmedRegions = rtrim($sortType,', ');
$trimmedRegionsCollection = explode(",", $trimmedRegions);
$trimmedRegionsRegex = implode("|", $trimmedRegionsCollection); // make string like Global|Middle East
$query = 'SELECT * from health_alerts_subscribers WHERE CONCAT(",", `Regions`, ",") REGEXP ",('.$trimmedRegionsRegex.'),"';
Hope it helps you.

Related

How do i get record by id in php

Here is my database view
I need to get title by using student id 232. But student id is stored in array like 192,229,232. How can i retrive 232 records only?
Please guide me..
Thanks
you use IN clause for get record from array
<?php
$sql = 'SELECT *
FROM `table`
WHERE `id` IN (' . implode(',', array_map('232', $array)) . ')';
Use FIND_IN_SET
Eg.
SELECT * FROM event WHERE FIND_IN_SET(232,student);
You can use LIKE condition to fetch results that contain this student id:
SELECT * FROM `event` WHERE student LIKE '%232%';
This will return you all rows that contain '232' in student column.
But if you have an opportunity to change your table structure I would suggest you to extract student column to a pivot table.
You could create event_student table that would contain just two columns: event and student. And each row would link particular student to a particular event. The data could be easily extracted with a simple JOIN:
SELECT * FROM `event` e
INNER JOIN `event_student` es ON e.eventID=es.event
WHERE es.student=232;
If you store connections between student and events this way you will gain flexibility in your queries and avoid possible mistakes that may occur when using the answer suggested above. Imagine that you have a student with id 2324 or 12323. Both of them contain desired '232' string and both will match the '%232%' pattern and lead to returning you wrong data.

how to remove repetition of data in mysql?

This is my detail table:
This is my contact table:
Here are two rows in details table and 4 rows (each details have 2) in contact table. When I use join query I get 4 results row but I want only 2 row(one row of details row with one contact of that corresponding details).
my query:
$this->db->select('*');
$this->db->from('dots_center_detail');
$this->db->join('dots_center_contact', 'dots_center_contact.registration_id = dots_center_detail.registration_id','left');
try this
$this->db->query("
SELECT DISTINCT dots_center_detail.registration_id, dots_center_contact.contact
FROM dots_center_detail
LEFT JOIN dots_center_contact ON dots_center_contact.registration_id = dots_center_detail.registration_id
")
Using select('DISTINCT *') in place of select('*') may give the result you need. It's worth a try.
Or you can create a view like this to go with your table definitions.
CREATE OR REPLACE VIEW dots_center_unique_contact AS
SELECT DISTINCT * FROM dots_center_contact;
Then refer to that dots_center_unique_contact view in your join operation.
Your best bet long term is to figure out why you have duplicate rows, and tighten up your business rules so you don't.

Retrieving Data from a field with comma delimitation SQL

I have a publications database and I need to fetch some information regarding the author. The author field is such that the authors have been lumped together in one field e.g if a book has two authors called Robert Ludlum and John Grisham, in the database it is saved as Ludlum, R.;Grisham,J.;
My application needs to spool information and retrieve data on books authored by a particular author if they click on their name. I am using this statement to retrieve the data
$select = "SELECT tblPublications.Title, tblPublications.Year FROM tblPublications WHERE tblPublications.Authors LIKE '%$sname%'";
$sname is a variable referring to the surname of the author. The problem arises if two authors share the same surname. however a workaround I am trying to implement is to get the applicationtake the surname, insert a comma, take the first name of a user and get the first letter then combine the result to a stringe and match them to each comma delimited value in the author field e.g if it is Grisham's books I am looking for I use *Grisham, J.* in my query.
Any Idea how to do this in PHP,MYSQL?
If it is possible to redesign the database, you should probably have an authors table and a book_authors table that relates books to authors, so that multiple authors can be associated with each book. Where is the Last Name coming from that the user clicks? Is it possible to have the link generated be LastName, First letter of first name? If so then you can probably change the link so it will include the first letter. But it is still possible to have two authors with the same last name and first letter of first name. So I think the best solution is to have an authors table and a Book_authors table and just store the author id as a hidden field and use that to retrieve the books by the selected author.
Your database design is incorrect, you have not normalized the data.
If you use like to search with leading wildcards, you will kill any chance of using an index.
Your only option to fix (if you want to keep the mistaken CSV data) is to convert the table to MyISAM format and put a FULLTEXT index on the authors field.
You can then search for an author using
SELECT fielda, b,c FROM table1 WHERE MATCH(authors) against ('$lastname')
See: http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html
Of course a better option would be to normalize the database and create a separate table for authors with a link table.
TABLE books
------------
id primary key
other book data
TABLE authors
--------------
id primary key
lastname varchar (indexed)
other author data
TABLE author_book_link
----------------------
author_id
book_id
PRIMARY KEY ab (author_id, book_id)
Now you can query using very fast indexes using something like:
SELECT b.name, b.ISBN, a.name
FROM books b
INNER JOIN author_book_link ab ON (ab.book_id = b.id)
INNER JOIN author a ON (a.id = ab.author_id)
WHERE a.lastname = '$lastname'
It would entirely depend on what input you are getting from the user.
If the user just types a name, then there isn't much you can do (as there is no guarantee that they will enter it in a correct format for you to parse).
If you are getting them to type in a firstname and lastname however, something like this could be done:
<?php
$firstname = trim(mysql_real_escape_string($_GET['fname']));
$surname = trim(mysql_real_escape_string($_GET['sname']));
$firstletter = substr($_GET['fname'],0,1);
$sname = $surname.', '.$firstletter;
$select = "SELECT tblPublications.Title,
tblPublications.Year
FROM tblPublications
WHERE tblPublications.Authors LIKE '%$sname%'";

php mysql search in 2 columns in 2 tables

I have two tables in one DB, one called Cottages and one called Hotels.
In both tables they have the same named fields.
I basically have a search bar that i want it to search in both of the fields in both of the tables. (the two fields being called "Name" and "Location"
SO far I have
$sql = mysql_query("SELECT * FROM Cottages WHERE Name LIKE '%$term%' or Location LIKE '%$term%' LIMIT 0, 30");
But this only searches the Cottages table, how can I make it search both the cottages and hotel tables?
Would be better if you merge both tables in only one and add a new field like type (with values like cottage or hotel) to identiy each record.
That's called normalization and it's exactly what WordPress do when it save posts, categories, attachments and pages on the sabe database table.
TiuTalk's answer is right - if the columns are the same in both tables you should probably only use one table for this data, and add a type column.
In addition using LIKE '%foo%' is slow. You should look into full text search. It also handles multiple tables in the same way as with LIKE plus you can sort by relevance. When sorting by relevance you get the most relevant rows first regardless of which table they came from.
If you can't change your design and you want to get exactly half the results from each table you can query each separately and use UNION ALL to combine the results:
(SELECT * FROM Cottages WHERE Name LIKE '%$term%' or Location LIKE '%$term%' LIMIT 15)
UNION ALL
(SELECT * FROM Hotels WHERE Name LIKE '%$term%' or Location LIKE '%$term%' LIMIT 15)
Obviously the columns must be the same in both tables for this to work. Don't use SELECT * though - you should explicitly list the column names otherwise reordering the columns could cause this query to break.

How to make search engine query in Mysql&PHP?

I want to make a search engine in an intranet. Now i use this clause in PHP.
$k = explode(" ",$_GET[key]);
$sql = "select entreprise.*, employee.* where entreprise.* or employee.* like '%$k[0]%' or '%$k[1]%'";
But it seems doesn't work. Do you know where is wrong?
Thanks in advance.
Edit:
$sql = "select * from entreprise, site, salarie where entreprise.*, site.*, salarie.* like '%$k[0]%' or '%$k[1]%'";
I have modified the query clause. With this code, i think you can know what i want to do.
I want to find anything that matches the content in all the columns of entreprise table and the content in all the columns of employee table.
It's hard to exactly see what you're trying to do, but you need, in your SQL query, to specify :
on which tables you are working, with a from clause
on which fields the search has to be done, in the where clause.
how the data between employees and enterprises are related :
do you want to search for entreprises and their employees ?
for employees and there enterprises ?
for all enterprises and the employees when the employee or the enterprise contains the words ?
You could use something like this to search for entreprises that contain the word, and get their employees to :
select *
from entreprise
inner join employee on employee.id_entreprise = entreprise.id
where entreprise.name like '%word%'
or entreprise.description like '%word%';
Or, to search for employees that match the criteria and get their entreprise too :
select *
from employee
inner join entreprise on entreprise.id = employee.id_entreprise
where employee.name like '%word%';
(just some ideas -- you'll have to build from there !)
This:
$sql = "select entreprise.*, employee.* where entreprise.* or employee.* like '%$k[0]%' or '%$k[1]%'";
is not valid SQL. It is hard to guess what you want to do, but I'm trying anyway: you want to find employees, and search them by name or by enterprise that employs them. Is that the case? Or do you want to search employess and/or enterprises?
EDIT
I want to find anything that matches the content in all the columns of entreprise table and the content in all the columns of employee table.
Ok, first of all you should realize that SQL is probably not the best tool for this job. See the other commenter - his suggestions about sphinx and friends are good. But still, if you really want to:
$sql = '
SELECT e.id, e.name
FROM enterprise e
-- first, look in column1
WHERE e.column1 LIKE '."'%".$k[0]."%'".'
OR e.column1 LIKE '."'%".$k[1]."%'".'
...etc for all entries in k...
OR e.column1 LIKE '."'%".$k[N]."%'".'
-- then, look in column2
OR e.column2 LIKE '."'%".$k[0]."%'".'
OR e.column2 LIKE '."'%".$k[1]."%'".'
...and so on and so forth for all entries in $k and all columns in enterprise...
UNION ALL
SELECT s.id, s.name
FROM salarie s
WHERE ...and the same for columns of salarie...
...
UNION ALL
...any other tables you want to search...
';
As you can see, not something that makes you happy.
Another approach that might give you more joy is having some overnight job to scan all rows in the tables you're interested in, parse the texts you want to search into separate words, and store those in a keyword table, and storing the association between an object from the source database and the keyword in a separate table. You can then search the keyword table and use the id's and table names you find for a collection of keywords to build the actual query to retrieve those rows. This is what I do, and it works great. It works better because there is a relatively small amount of words that you will encounter, whereas the collection of objects is quite possible very large.

Categories