MySQL order by how much it's like a string - php

I have the following MySQL query:
SELECT * FROM users WHERE name LIKE '%jack%'
I want it to order by how much it's like jack so
jack
jacker
majack
I can also use PHP.

I think you can accomplish what you want by using full text search function in mysql. Your query will be like this:
SELECT name, MATCH (name) AGAINST ('jack') as score
FROM users ORDER BY score DESC;
There are some conditions you need to take into consideration when using full search text:
The mysql engine should support this functions. I think InnoDB 5.6 and MYISAM 5.5 support that.
You have to add a FULLTEXT index in your table definition.
You can see a working demo here: http://sqlfiddle.com/#!9/72bf5/1
More info about full search text in MySQL here: http://dev.mysql.com/doc/refman/5.0/en/fulltext-natural-language.html
Also, here is a working example I wrote on PHP using similar_text and sorting array functions: http://ideone.com/UQpBFk
Hope it helps!

I don't think you can do this kind of thing with plain SQL. The first thing you need to do is define what it means for two strings to be similar, for which there are various metrics. You should probably pick one of those and write a stored procedure to sift through the data.

As every one mentioned, you can't achieve this using normal way other than using full text search but if you know all the different pattern before hand then you can use FIELD function to achieve something which resemble a approx result like
SELECT * FROM users WHERE name LIKE '%jack%'
ORDER BY FIELD (name,'jack','jacker','majack')

Try something like this:
$query = mysql_query("SELECT * FROM users WHERE name LIKE '%jack%' ORDER BY name ASC ");
while($fetchdata=mysql_fetch_array($query))
{
echo $fetchdata["name"] ;
}

Related

How to match Value from string in Mysql PHP

I have a table methodology in mysql where a column contain values like 1,2,3,4,5,6 or 3,4,6 or 25,4,7,8 in multiple row.
Now in my scenario i have a company which contain id 6 and i want to Match this value with methodology table value. But i don't have any idea how i can do it.
I am trying that first it get all values from methodology table one by one and after that match value of company.
can anyone please help me??
You can use FIND_IN_SET(your_id, columnname) function.
Query will be like
SELECT * FROM
methodology
where FIND_IN_SET(your_id, columnname)
For more details about function please refer : http://www.w3resource.com/mysql/string-functions/mysql-find_in_set-function.php
Use LIKE from mysql queries.
An example :
SELECT row FROM my_table WHERE my_column LIKE %6%
You need to use find_in_set function
http://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_find-in-set
To elaborate on #matthiasbe's incomplete answer, if you want to use LIKE, you should do as follows :
SELECT * FROM methodology WHERE companies LIKE '%,6,%' OR companies LIKE '6,%' OR companies LIKE '%,6'
This will match all rows where companies either has ,6, in its value or begins with 6, or ends with ,6.
This is far from being a perfect solution (both in clarity of the code and execution time), I'm just listing the options, hope it helps.

Searching a field for the whole word, and nothing but the word

I have a PHP interface with a keyword search, working off a DB(MySQL) which has a Keywords field.
The way in which the keywords field is set up is as follows, it is a varchar with all the words formatted as shown below...
the, there, theyre, their, thermal etc...
if i want to just return the exact word 'the' from the search how would this be achieved?
I have tried using 'the%' and '%the' in the PHP and it fails to work by not returning all of the rows where the keyword appears in.
is there a better (more accurate) way to go about this?
Thanks
If you want to select the rows that have exactly the keyword the:
SELECT * FROM table WHERE keyword='the'
If you want to select the rows that have the keyword the anywhere in them:
SELECT * FROM table WHERE keyword LIKE '%the%'
If you want to select the rows that start with the keyword the:
SELECT * FROM table WHERE keyword LIKE 'the%'
If you want to select the rows that end with the keyword the:
SELECT * FROM table WHERE keyword LIKE '%the'
Try this
SELECT * FROM tablename
WHERE fieldname REGEXP '[[:<:]]test[[:>:]]'
[[:<:]] and [[:>:]] are markers for word boundaries.
MySQL Regular Expressions
if you also search for the commas, you can be sure you are getting the whole word.
where keywordField like '%, the, %'
or keywordField like '%, the'
or keywordField like 'the, %'
maybe I didn't understand the question properly... but If you want all the words where 'the' appears, a LIKE '%word%' should work.
If the DB of words is HUGE MySQL may fail to retrieve some of the words, that can be solved in 2 ways...
1- get a DB that support bigger sizes (not many ppl would chose this one tho). For example SQL Server has a 'CONTAINS' function that works better than LIKE '%word%'.
2- use a external search tool that uses inverted index search. I used Sphinx for a project and it works quite good. This is better if you rarely UPDATE the rows of the data you want to search from, which should be the case.
Sphinx for example would generate a file from your MySQL table and use this file to solve the search (it's very fast), this file should be re-indexed everytime you do a insert or update on the table, making it a much better solution if you rarely update or insert new rows.
It looks like you have a one to many relationship going on within a column. It might be better to create a separate table for keywords with a row for each keyword and a foreign key to whatever it is you're searching on.
Doing like '%???%' is generally a bad idea because the DB can't make use of an index so it will scan the whole table. Whether this matters will depend on the size of data you're working with but its worth considering up front. The single best way to help DB performance is in the initial table design. This can be tricky to change later.

Trying to do a php/mysql search and need to break string into array and search

My users put search terms in an input field. The script I'm using stores that in a $find variable. It then searches mysql like so:
"select * from mytable WHERE title LIKE '%$find%' or description LIKE '%$find%'";
I want to be able to pull a result, even if 1 word is in the title and another in the description, which currently doesn't happen. So.. I'm guessing I need to break the $find variable into an array with a function. After that, how would I do the search in mysql? Since I never know how many words will be in the search (they might decide to search for 8 words at once), how do I reference the array in the mysql query?
Thx in advance!
You should use a FULLTEXT index and build a proper boolean search query on it.
You MAY achieve the effect you want without it, but this would be very slow compared to using FULLTEXT index. You would have to use explode to get the list of words, then build a WHERE condition like concat(title, description) LIKE '%word1%' AND concat(title, description) LIKE '%word2%' etc.
(In my first answer I stated that achieving this effect is impossible without FULLTEXT. I was wrong and edited this answer.)

Comparing different data-types in PostgreSQL.

it's been a while since I have made one of my "Converting MySQL to PostgreSQL" posts.
So, today's problem is as follows:
The original MySQL queries involve where clauses which look a bit like the following:
WHERE id LIKE '%6%'
OR createdtime LIKE '%6%'
OR modifiedtime LIKE '%6%'
OR start_date LIKE '%6%'
OR end_date LIKE '%6%'
OR sc_related_to LIKE '%6%'
OR tracking_unit LIKE '%6%'
OR message LIKE '%6%'
This query is part of a system wide search. In this case, the system is searching for 6, had I asked it to search for something else, like say the word user, instead of %6%, we'd have %user%.
Now, the problem is that, the above data-types are not always strings. Integer fields like id and date/time fields like createdtime are being compared to strings. In MySQL, this seems to be okay, but grumpy PostgreSQL gets grumpy when it sees this query.
I know that for some fields, I can use the to_char function, so, for example, part of the clause in PostgreSQL might look like this:
to_char(id, '999') LIKE '%6%'
Unfortunately, I can't just go throught the queries and add the to_char to each applicable field because of the PHP backend. This is what the PHP code for generating the WHERE clause looks like:
$where .= $tablename.".".$columnname." LIKE '". formatForSqlLike($search_val) ."'";
Note: It's part of a loop, so the above line generates all of the individual comparisons.
So, even if I can get around the type comparison with to_char, I can't implement it because to_char might need a specific 2nd parameter for a different data-type and even if I could use the same parameter for all data-types, some of the data-types would be strings, and passing a string to to_char throws an error.
So, I need a way to either get PHP to determine the column type and use the right to_char(or don't use it at all) accordingly or I need to get PostgreSQL to compare different data-types.
Thanks for all of your help, have a good day!
You could just cast everything to a string, such as:
$where .= $tablename.".".$columnname."::text LIKE '". formatForSqlLike($search_val) ."'";
If you don't want to change the PHP code, another idea is to create a VIEW that does the cast, such as:
CREATE OR REPLACE VIEW TableName AS
SELECT
createdtime::text,
modifiedtime::text,
start_date::text,
end_date::text,
sc_related_to::text,
tracking_unit::text,
message::text
FROM RealTable;
Then your PHP code would just use this view instead of the table, and see everything as text.
However, I believe your technique here is really not going to scale well. Every search will probably be doing a sequential scan of the entire table, since LIKE clauses cannot be indexed.
Your best bet is to re-design this using a FULLTEXT search index, which will be way more versatile as well as lightning fast.

MySQL - Filter result

I want to filter result of my SQL query. I want to select everything that has some specific text in some column.
Example:
SELECT * FROM categories WHERE (name
has 'abc' values in it's value ex.
MyabcCategory)
Also maybe it is not very good idea to do that in query, maybe it is better to get all and then filter array instead? But I don't know how to do that aether.
Use LIKE with % wildcard:
SELECT * FROM categories WHERE name LIKE '%abc%'
This will give you all the records that have abc somewhere in them.
You can learn more about it here :)
You want to use the LIKE operator, with % to match any character before and after your specific word :
select *
from categories
where name like '%abc%';
But note that doing so, MySQL will scan each line of the table, every time the query is executed... which might not be great if you have a lot of data.
If you're searching for some kind of text, you might either want to :
Use a FULLTEXT index, if you're working with MyISAM tables.
Or, use a solution that's separated from MySQL, with a specific indexing/search engine, such as Solr.
SELECT * FROM categories WHERE name LIKE '%abc%'

Categories