LIKE condition : why '%,x,' doesn't work but '%,x,%' works - mysql

i have table called image
there is column called category in that table which varchar and stores all the categories of an image sperated with comma .
i one row i have :
category : ,26,25,
this query works fine
SELECT *
FROM `images`
WHERE `confirm` =1
AND `category` LIKE '%,25,%' AND `category` LIKE '%,26,%'
LIMIT 0 , 20
and i get all the rows with ,25,26, as their category
but
why this doesn't work ?
SELECT *
FROM `images`
WHERE `confirm` =1
AND `category` LIKE '%,25,' AND `category` LIKE '%,26,'
LIMIT 0 , 20

LIKE matches the entire string. LIKE '%,26,' matches strings that end in ,26,, not strings that contain it. You need % on both ends if you want to search for a substring anywhere.

LIKE must match the entire value in the table. If there is content in the table after the "25,", then LIKE '%,25,' will not match it.
If you want regular expression matching in mysql, you can use RLIKE:
AND category RLIKE ',25,' AND category RLIKE ',26,'
but if you use LIKE, you have to match the whole thing.

The like is an exact match, not a match for something arbitrarily inside the string. You need wildcards to say that you want a match somewhere inside.
The expressions:
AND `category` LIKE '%,25,' AND `category` LIKE '%,26,'
Are looking for cases when category ends in ',25,' AND ends in ',26,' at the same time. Clearly, this is not possible.
You can also phrase this in MySQL as:
AND find_in_set(25, category) > 0 and find_in_set(26, category) > 0
Also, you should have a separate table that has one row per category. Such queries would be much easier and more efficient with a proper relational data structure.

Related

MySQL - WHERE x IN ( column)

I tried something out. Here is a simple example in SQL Fiddle: Example
There is a column someNumbers (comma-seperated numbers) and I tried to get all the rows where this column contains a specific number. Problem is, the result only contains rows where someNumbers starts with the specific number.
The query SELECT * FROM myTable where 2 in ( someNumbers ) only returns the row with id 2 and not the row with id 1.
Any suggestions? Thank you all.
You are storing data in the wrong format! You should not be storing multiple values in a single string column. You should not be storing numbers as strings. Instead, you should have a junction table with one row per id and per number.
Sometimes, you just have no choice, because someone else created a really poorly designed database. For these situations, MySQL has the function find_in_set():
SELECT *
FROM myTable
WHERE find_in_set(2, someNumbers ) > 0;
The right solution, however, is to fix the data model.
While Gordon's answer is a good one, here is a way to do this with like
SELECT * FROM myTable where someNumbers like '2,%' or someNumbers like '%,2,%' or someNumbers like '%,2'
The first like checks if your array starts with the number you are looking for (2). The second one checks if 2 is within the array and the last like tests for appearance at the end.
Note that the commas are essential here, because something like '%2%' would also match ...,123,...
EDIT: As suggested by the OP it may happen that only a single value is present in the row. Consequently, the query must check this case by doing ... someNumbers = '2'
I would suggest this query :
SELECT * FROM myTable where someNumbers like '%2%'
It will select every entry where someNumbers contains '2'
Select * from table_name where coloumn_name IN(value,value,value)
you can use it

SELECT rows that contain specific alphanumeric characters in MySQL

I'm trying to select all rows that contain only specific alphanumeric characters in MySQL using:
SELECT * FROM table WHERE column LIKE '%abc%' OR column LIKE '%abd%'
OR column LIKE '%ab%'
For instance:
abc1234 is ok
abd1234 is ok
abe1234 is not ok
abg4567 is not ok
ab1234 is ok
ac1234 is not ok
The problem is, it select all the "abe","abg". How to select abc1234, abd1234 and ab1234?
With this
OR column LIKE '%ab%'
As part of the WHERE clause, it's no surprise that abe and abg are selected.
Please permit me to also mention that queries LIKE '%something%' cannot make use of any indexes and are likely to be very slow on large tables. The fact that you have three of them in one query is only going to make it worse.
Use the below Query which will also use indexes on column column
SELECT * FROM table WHERE column LIKE 'ab%' AND column not LIKE 'abe%'
AND column not LIKE 'abg%'
The Reason the indexes will be used in this case is the query is not using wildcard in the beginning of the string literal
Remove the last part of your query, it is telling it to select abg and abe.
You have told it to select all items beginning with anything and ending with anything providing ab is in the middle.
Because column LIKE '%ab%' will get "abe" or "abg"
If you want number after "ab", this is your query:
SELECT * FROM table WHERE column LIKE '%abc%' OR column LIKE '%abd%'
OR column LIKE '%ab0%' OR column LIKE '%ab1%' OR column LIKE '%ab2%' OR column LIKE '%ab3%' OR column LIKE '%ab4%' OR column LIKE '%ab5%' OR column LIKE '%ab6%' OR column LIKE '%ab7%' OR column LIKE '%ab8%' OR column LIKE '%ab9%'
Are you going to select column contain "abc" or "abd" or "ab" but not "abe"or "abg". For this case i don't think you can use LIKE. Try to use REGEXP. i think "ab[^g^e]?" should do the job for you.
SELECT name FROM table WHERE column REGEXP 'ab[^g^e]?';

Ordering mysql result by number of regexp matches

I've the following query. It selects all posts where the title contains the words green, blue or red.
SELECT id, title FROM post WHERE title REGEXP '(green|blue|red)'
I would like to sort the results in such a way that the title with the most matches (all three words) and thus the most relevant one, is listed first. Is this possible in this scenario and if so, how I would go on about it?
Thanks
You must split the regex. Either to different conditions or different queries:
SELECT COUNT(results.username) as count, results.* FROM (
SELECT * FROM `post` WHERE `title` LIKE "%blue%"
UNION SELECT * FROM `post` WHERE `title` LIKE "%red%"
UNION SELECT * FROM `post` WHERE `title` LIKE "%green%"
) as results GROUP BY results.title ORDER BY count DESC;
Note: I used LIKE instead of REGEXP, becouse when you split the condition you wont need it anymore according to your example. LIKE is a bit faster then regex, but if your pattern is more complex, then you can always replace it back.

mysql search LIKE not working for long phrase

I have a MySQL table, type 'MyISAM', collation: 'latin1_swedish_ci'. Inside it, I have a column named 'content'.
Inside there, I have a row with the following content:
<p>The state will have a different advantage over most other states, with one of the largest populations in the nation to blablablabla. </p>
My query is this in phpMyAdmin and also in my PHP file:
SELECT *
FROM `pages`
WHERE `content` LIKE '%with one of the largest populations%'
ORDER BY `pages`.`title` ASC
LIMIT 0 , 30
0 rows are returned.
The weird thing is that if I edit the query to this:
SELECT *
FROM `pages`
WHERE `content` LIKE '%with one of the largest%'
ORDER BY `pages`.`title` ASC
LIMIT 0 , 30
Then , 1 rows are returned, and it works.
Is there any setting that might limit the search query to only a few words or only a few characters?
Most probably there are any other whitespace character(s), otherwise, your query seems fine.
try this largest populations should also return 0 recs.
So replace, those characters from column before, searching.
You can find some help here

Prepare mysql row for use in IN() clause

I need to find rows that contain a specific number in a set of numeric values that are stored in a table. I'm using the WHERE IN() function of mysql, but I'm having problems with the proper format.
Basically I have the following query:
SELECT id,category, text
FROM ws_cat
WHERE '11' IN (category)
The category field is a VARCHAR and looks like the following:
id category
1 11
2 12,11
3 1,13,9
So I need to find the rows with id 1 and 2 in this case. Unfortunately it doesn't work and I'm guessing it's because of the missing quotes, but all the ideas of reformating with QUOTES() or just changing the format of category to something like '12','11' wouldn't work either. Both would be possible for me as long as it works...
Use the FIND_IN_SET function:
SELECT id, category, text
FROM ws_cat
WHERE FIND_IN_SET('11', category) <> 0;