MySQL - Filter result - php

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%'

Related

sql statement syntax for search

I would like to write an sql statement for search. Here is sample database structure.
For eg, I want to display all records with topic '13'. How can i write sql query for searching 13 from the above structure? Any suggestions?
Can i able to use WHERE Topic LIKE '%13%'? Anything wrong with this?
Try this one:
SELECT * FROM `TABLE_NAME` WHERE `Topic` LIKE "%13%";
It's better and faster to save it in a third table of many-to-many relationship.
If you want to save as per your example (single table), try to save data as eg ",10,13,15,"
always have coma before and after, thus the following sql will exclude 213 and 132 etc
select * from table_name where Topic like '%,13,%'
select * from table where find_in_set("13",topic);
or if topic is not used as a set, you could do ...
select * from table where concat(",",topic) like "%,13,%";
The 2nd isn't real elegant but I've had to do that a couple times.
Because the data isn't really normalized, I used concat to add a comma to the topic field so I could make sure the "like" comparison would pass with a comma before and after the value. I suppose we would also have to remove any unwanted spaces as well for this example, so ultimately it would end up like:
select * from TABLE where concat(",",replace(topic," ","")) like "%,13,%";
Ultimately, we have to know what to expect in the topic column to come up with a query that would always work. In the past, I've had situations where I would add values to a string field (i.e. topic) with a delimiter before and after each value like:
(1)(2)(3)(14)(15)(255)(283)
If you did something like this for the topic field, the query is simple ...
select * from table where topic like "%(13)%";

MySQL order by how much it's like a string

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"] ;
}

Querying a table where the field contains any order of given text strings

I want to query a table as follows:
I have a field called "category" and my input match contains N separate words. I want the query to match all rows that contain all N words, but in any order.
For example if the field category contains "hello good morning world", my input query can contain "hello morning" or "good" or "world hello" and all are matches to the query.
How do I formulate such an SQL expression?
Also it would be good if the query can be made case insensitive.
If you are using MySQL you can use the boolean fulltext search feature to achieve this. You can put a + in front of each term and then only results with all the terms, in any order, will be returned. You will need to make sure the column containing the category field has a fulltext index specified on it for this to work. Other database engines probably have similar features. So for example you might do something like the following assuming there were a fulltext index over the category column...
SELECT * FROM myTable WHERE MATCH (category) AGAINST ('+term1 +term2 +term3' IN BOOLEAN MODE);
I would avoid using the "LIKE" operator as others have suggested you would have to worry about the headache of mixed upper/lower case and if you have a large database using a % in the front of a LIKE search term is going to cause a full table scan instead of using an index which is horrible for performance.
I'm not writing the loop that will build this query for you. This will get the job done, but it will be pretty inefficient.
SELECT * FROM table
WHERE (
TOUPPER(category) LIKE '*HELLO*' AND
TOUPPER(category) LIKE '*GOOD*' AND
TOUPPER(category) LIKE '*MORNING*' AND
TOUPPER(category) LIKE '*WORLD*'
);
You could also research using REGEXes with SQL.

Check if mysql field contains a certain number in mysql query

I am having a table with a column that has few ids that were put into database with multi select. Column for example contains: 1,4,5,7,9. Is it possible to check if this column contains for example number 5 or not in it through MySQL query ?.
I need to select all the people that have number 5 or some other listed in that field and print them through php.
http://dev.mysql.com/doc/refman/5.6/en/string-functions.html#function_find-in-set
SELECT ...
WHERE FIND_IN_SET(5, list_column)
But understand that this search is bound to be very slow. It cannot use an index, and it will cause a full table-scan (reading every row in the table). As the table grows, the query will become unusably slow.
Please read my answer to Is storing a delimited list in a database column really that bad?
You can use #MikeChristensen's answer to be more standard. Another trick with standard SQL is this:
select * from TableName
where ',' || ids || ',' LIKE '%,5,%'
(in standard SQL, || is the string concatenation operator, but in MySQL, you have to SET SQL_MODE=PIPES_AS_CONCAT or SET SQL_MODE=ANSI to get that behavior.)
Another MySQL-specific solution is to use a special word-boundary regular expression, which will match either the comma punctuation or beginning/end of string:
select * from TableName
where ids RLIKE '[[:<:]]5[[:>:]]'
None of these solutions scale well; they all cause table-scans. Sorry I understand you cannot change the database design, but if your project next requires to make the query faster, you can tell them it's not possible without redesigning the table.
Perhaps:
select * from TableName
where ids = '5' -- only 5
or ids like '5,%' -- begins with 5
or ids like '%,5' -- ends with 5
or ids like '%,5,%' -- 5 in the middle somewhere
It probably won't be very fast on large amounts of data. I'd suggest normalizing these multi-selection values into a new table, where each selection is a single row with a link to TableName.
select * from your_table where concat(',',target_column,',') like '%,5,%'
you can write the sql query like this, for example you are looking for the number 5
select * from your_table_name where ids='5'
if you want to check the result with php just tell me i will write it for you :)

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.

Categories