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.
Related
I'm trying to make a search feature that will search multiple columns to find a keyword based match. This query:
SELECT title FROM pages LIKE %$query%;
works only for searching one column, I noticed separating column names with commas results in an error. So is it possible to search multiple columns in mysql?
If it is just for searching then you may be able to use CONCATENATE_WS.
This would allow wild card searching.
There may be performance issues depending on the size of the table.
SELECT *
FROM pages
WHERE CONCAT_WS('', column1, column2, column3) LIKE '%keyword%'
You can use the AND or OR operators, depending on what you want the search to return.
SELECT title FROM pages WHERE my_col LIKE %$param1% AND another_col LIKE %$param2%;
Both clauses have to match for a record to be returned. Alternatively:
SELECT title FROM pages WHERE my_col LIKE %$param1% OR another_col LIKE %$param2%;
If either clause matches then the record will be returned.
For more about what you can do with MySQL SELECT queries, try the documentation.
If your table is MyISAM:
SELECT *
FROM pages
WHERE MATCH(title, content) AGAINST ('keyword' IN BOOLEAN MODE)
This will be much faster if you create a FULLTEXT index on your columns:
CREATE FULLTEXT INDEX fx_pages_title_content ON pages (title, content)
, but will work even without the index.
1)
select *
from employee em
where CONCAT(em.firstname, ' ', em.lastname) like '%parth pa%';
2)
select *
from employee em
where CONCAT_ws('-', em.firstname, em.lastname) like '%parth-pa%';
First is usefull when we have data like : 'firstname lastname'.
e.g
parth patel
parth p
patel parth
Second is usefull when we have data like : 'firstname-lastname'. In it you can also use special characters.
e.g
parth-patel
parth_p
patel#parth
Here is a query which you can use to search for anything in from your database as a search result ,
SELECT * FROM tbl_customer
WHERE CustomerName LIKE '%".$search."%'
OR Address LIKE '%".$search."%'
OR City LIKE '%".$search."%'
OR PostalCode LIKE '%".$search."%'
OR Country LIKE '%".$search."%'
Using this code will help you search in for multiple columns easily
SELECT * FROM persons WHERE (`LastName` LIKE 'r%') OR (`FirstName` LIKE 'a%');
Please try with above query.
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.
I am searching from 3 tables currently (will search in more after sorting this out). This query brings all the results in the order of the tables listed in query. Whereas I want to get the most relevant search results first.
(Select name, url, text, 'behandlinger_scat' AS `table` from behandlinger_scat where name LIKE '%KEYWORD%' OR text LIKE '%KEYWORD%')
UNION
(Select name, url, text, 'hudsykdommer_scat' AS `table` from hudsykdommer_scat where name LIKE '%KEYWORD%' OR text LIKE '%KEYWORD%')
UNION
(Select name, url, text, 'om_oss' AS `table` from om_oss where name LIKE '%KEYWORD%' OR text LIKE '%KEYWORD%')
Any help would be appreciated.
You can use a method to order by the points you dynamically give the results, as in this example (you will need to alias your tables so SQL will understand what column you're referring to):
ORDER BY
CASE WHEN name LIKE table.keywords THEN 100 ELSE 0 END +
CASE WHEN name LIKE table2.keywords THEN 10 ELSE 0 END +
CASE WHEN text LIKE table2.keyword THEN 1 ELSE 0 END
DESC
This is merely an example, but the concept is the following:
You decide how many "points" each "match" will receive (e.g name matches keyword is 100 points, text matches it - a little less) then, each row "accumulates" points with correlation to its matches, and the row with the most points shows first.
I have a table that contains 3 text fields, and an ID one.
The table exists solely to get collection of ID's of posts based on relevance of a user search.
Problem is I lack the Einsteinian intellect necessary to warp the SQL continuum to get the desired results -
SELECT `id` FROM `wp_ss_images` WHERE `keywords` LIKE '%cute%' OR `title` LIKE '%cute%' OR `content` LIKE '%cute%'
Is this really enough to get a relevant-to-least-relevant list, or is there a better way?
Minding of course databases could be up to 20k rows, I want to keep it efficient.
Here is an update - I've gone the fulltext route -
EXAMPLE:
SELECT `id` FROM `wp_ss_images` WHERE MATCH (`keywords`,`title`,`content`) AGAINST ('+cute +dog' IN BOOLEAN MODE);
However it seems to be just grabbing all entries with any of the words. How can I refine this to show relevance by occurances?
To get a list of results based on the relevance of the number of occurrences of keywords in each field (meaning cute appears in all three fields first, then in 2 of the fields, etc.), you could do something like this:
SELECT id
FROM (
SELECT id,
(keywords LIKE '%cute%') + (title LIKE '%cute%') + (content LIKE '%cute%') total
FROM wp_ss_images
) t
WHERE total > 0
ORDER BY total DESC
SQL Fiddle Demo
You could concatenate the fields which will be better than searching them individually
SELECT `id` FROM `wp_ss_images` WHERE CONCAT(`keywords`,`title`,`content`) LIKE '%cute%'
This doesn't help with the 'greatest to least' part of your question though.
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.