Internal site search is matching exact word only - php

I am making an eCommerce website I am using PHP and Mysql and I have some products name in table named product. How can I make a search system by which if I type "Wallnuts", it should return all results having word "wallnut, walnut, walnuts" and word with same pronunciation like "valnuts" and sorted as best matching result first. For this I am trying this by this query :
select product_name,photo,in_stock,sell_price
from $tbl_product
where product_name like '%".$q."%'
ORDER BY (CASE WHEN product_name LIKE '".$q."%' THEN 1
WHEN product_name LIKE '%".$q."%' THEN 2 ELSE 3
END) limit 0,10
Where $q is search string. By this query I am getting result but with only exact word match.
I need result like on Bigbasket.com for word wallnuts, wallnut, walnts, valnuts.

The closest you can try is SOUNDEX() function in MYSQL.
select * from mytext
where soundex(val) LIKE CONCAT('%',SOUNDEX('wallnut'),'%')
This gives me wallnuts, wallnut, walnts.Check Demo here

Related

ordering sql select results

i am selecting data from sql by this command:
the command can contain more then one words like
select * from table where title like '%deadpool%' ////1
or
select * from table where title like '%deadpool%' && like '%world%' ////2
so this show results like :
*****************1*************
thenewdeadpoolishere
deadpool
*****************2*************
.deadpool.world.
deadpool world
now, i want to order the list as follows :
*****************1*************
deadpool
thenewdeadpoolishere or whatever
*****************2*************
deadpool world
cdsghjvjdhgdeadpoolvworlddsbvs or whatever
the thing is i want to order it somehow that if the whole word of searched term is present in the result then it should show up first.
I suspect you are looking for:
select t.*
from table t
where title like '%deadpool%' and
title like '%world%'
order by ((title like '%deadpool%') + (title like '%world%')) desc;
However, it is quite likely that you really want full text search, with order by relevancy. You can check the documentation to see if this is what you really want.

mysql - multiple CASE statements for multiple columns with relevance (matching rank) of whatsoever value

This is a search inside multiple columns in a MySQL table with multiple keywords.
$query="select *
,case when prod_name like '%$search%' then 1 else 0 end as name_rank
, case when prod_code like '%$search%' then 1 else 0 end as code_rank
, case when prod_brand like '%$search%' then 1 else 0 end as brand_rank
from products
where prod_name like '%$search%'
or prod_code like '%$search%'
or prod_brand like '%$search%'
order by (name_rank + code_rank + brand_rank ) desc";
When the search keywords (i.e: prod 123) are given as input in the search form, the landing URL becomes : http://localhost/shop/index/search?search=prod+123.
I get the query parameter in the following way :
$search=$_GET['search'];
Then the above query returns rows for which any single column contains both keywords. For example if column prod_name has fine prod and column prod_brand has '123', the query won't return this row.
1) Obviously I need to return that row as well
Again, when the search keyword is a single word i.e: prod and row 1 has product new in prod_name column and row 2 has only prod in the same column, then row 2 should come before row 1 in results. Shouldn't it? I think unlike the query, it needs to detect any relevance in between 0 and 1
2) How to make the results reflect this relevance or priority as well ?
I am using PHP (i.e. CodeIgniter framework) by the way.
How to achieve both points 1 and 2 ?

MySQL query order by multiple items not working

I´m currently working on a query that must pull up titles ordered by
Exact match,
Followed by Highest amount of matched words first,
Followed by First word in query is first word in title,
Followed by Alphabetical order.
Something like this:
SELECT title
FROM title
WHERE title LIKE '%keyword%' OR LIKE '%keyword1%' OR LIKE '%keyword2%'
order by
case when title == 'keyword' then 0 else 1 end asc,
((title like '%keyword1%') + (title like '%keyword2%')) desc,
case when title like 'keyword1%' then 0 else 1 end asc,
title asc;
I tested with 8 titles.
Search: "Buford Christmas".
Result:
Buford Christmas
Christmas Buford
Mr Buford
Mr Buford
Buford and Lisa
Lisa Christmas
Me Christmas
Me Buford Lisa.
I need to find a way to sort the titles so that "Buford and Lisa" should be before "Mr Buford".
They keyword in the query may have any number of sub-keywords, causing the code in the MySQL statement to change dynamically. My example code was generated with a keyword that has 2 sub-keywords. The part that seems not to be working is: "case when title like 'keyword1%' then 0 else 1 end asc" I am wondering if the code is in the wrong position in the comma delimited order sequence or if I should assign different numbers to 'then' and 'else'.
About my select code:
In my select statement if the keyword is "Buford Christmas" it's broken into "Buford" and "Christmas" and "Buford Christmas".
About this part of order code:
((title like '%keyword1%') + (title like '%keyword2%')) desc,
MySQL treats boolean expressions as numbers, with true being 1. So, this counts the number of matches.
select title
from books
where title like '%buford christmas%'
or title like '%buford%'
or title like '%christmas%'
order by
case
when
title = 'buford christmas' then 1
when
title like '%buford%' and title like '%christmas%' then 2
when
title like 'buford%' then 3
when
title like '%buford%' then 4
when
title like 'christmas%' then 5
when
title like '%christmas%' then 6
end
asc;
This will do what you're looking for. Obviously substitute variables for the literals there. It prioritises results as such:
Books with title that EXACTLY matches the keywords
Books with titles that CONTAIN BOTH keywords
Books with titles that START with the first keyword
Books that CONTAIN the first keyword
Books that END with the last keyword
Books that CONTAIN the last keyword
Demo: http://sqlfiddle.com/#!9/ec62a/7
edit
You may also want to consider a fulltext index, eg: create fulltext index ftx_title on books(title), you could then run your query as such:
select *
from books
where match(title)
against ('buford christmas' in boolean mode);
Which would make crafting your queries for keywords quite a bit simpler

Query order results according to search results

I am creating a search function and take an input parameter and query my database using the following query:
select * from people where title like '{param}%' or title like '%{param}%';
my question is that this returns all the records as they are meant to but I want to order the results so that the results of the where statement 'title like '{param}%'' return first then the following where statement.
Is there any way to do this?
Try that :
select * from people where title like '{param}%' or title like '%{param}%'
ORDER BY CASE when title like '{param}%' then 0
when title like '%{param}%' then 1 end asc
I would write this as:
select *
from people
where title like '{param}%' or title like '%{param}%'
order by (title like '{param}%') + (title like '%{param}%') desc;
MySQL treats boolean results as integers so you can add them together. Clearly, if something starts with {param}, then it also contains it, so those will have a value of 2.

Getting most relevant results when searching from multiple tables (php, mysql)

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.

Categories