I have got a filed in my database table which stores categories. I am storing the categories in the following format:
1,12,15
Now when I try to search for a product from category 1,
I use LIKE clause in my query such as
where (prod_catg LIKE %1,% or prod_catg LIKE %1% or prod_catg LIKE %,1% )
This returns me the products from all the three categories 1,12 and 15. Instead I just want the products from category 1.
I have also tried IN clause but no results found.
Can anyone please suggest me some other alternative.
prod_catg LIKE '1,%' --matches when 1 is the first category
OR prod_catg LIKE '%,1,%' --matches when 1 is somewhere in the middle
OR prod_catg LIKE '%,1' --matches 1 when is the last category
anyway you had better to refactor your schema by adding a category table and the reference to it on the product (main) table
EDIT
another way to face this problem is using REGEXP which will lead to a shorter WHERE clause (here is what i've used to test):
DECLARE #regexp VARCHAR(100);
SET #regexp = '^1,.*|.*,1$|.*,1,.*';
SELECT
'1,11,15,51,22,31' REGEXP #regexp AS test1,
'51,11,15,1,22,31' REGEXP #regexp AS test2,
'11,15,51,22,31,1' REGEXP #regexp AS test3,
'7,11,15,51,22,31' REGEXP #regexp AS test4,
'51,11,15,7,22,31' REGEXP #regexp AS test5,
'11,15,51,22,31,7' REGEXP #regexp AS test6;
this will match your prod_catg against the Regular Expression '^1,.*|.*,1$|.*,1,.*' returnig 1 (TRUE) if it matches, 0 (FALSE) otherwise.
Then your WHERE clause will look like:
WHERE prod_catg REGEXP '^1,.*|.*,1$|.*,1,.*'
explanation of regexp:
^1,.* --matches 1 at the beginning of a string followed by a `,` and any other char
.*,1$ --matches 1 at the end of a string preceded by a `,` and any other char
.*,1,.* --matches 1 between two `,` which are sourrounded by any other chars
| --is the OR operator
i'm sure this regexp could be much more compact but i'm not that good with regular expressions
obviuosly you can change the category you're looking for in the regular expression (try to replace 1 with 7 on the example above)
WHERE FIND_IN_SET('1', prod_catg)
You have a many to many relation between products and categories. You should create a new table to store the coresponding categories(cat_ids) for each product. You shouldn't have a column containing multiple category ids. This way your select would be much easier and a lot faster.
Related
I am joining the tables Table_A and Table_B on columns Col_A and Col_B. Below are some test sample values.
Table_A, Col_A
USA1FullCover
USAMainland
USA2Islands
Table_B, Col_B
USA
USA1
USA2
When joining, I need to match the value 'USA' followed by a number exactly. For instance, the join result should look like this.
Col_A Col_B
USA1FullCover USA1
USAMainland USA
USA2Island USA2
I'm trying to achieve this in MySQL. I tried the rlike function. But the issue is that with rlike, I am not able to completely match them.
select
case when 'USA1FullCover' rlike 'USA' then 1 else 0 end;
#matches, but shouldn't
select
case when 'USA1FullCover' rlike 'USA1' then 1 else 0 end;
#matches, which is what I need/expect
select
case when 'USA1FullCover' rlike 'USA2' then 1 else 0 end;
#doesn't match, which is what I need/expect
My question is how can I fix the rlike so that the first case doesn't happen i.e. it doesn't match when there is no digit on the RHS? Or is it possible using regex? Taking a substring of the LHS doesn't help since we cannot really define the length beforehand.
Use
col_A regexp '^USA[0-9]{1}.+$'
to match USA followed by exactly one digit followed by any other characters.
To join only when such pattern exists
select a.*,b.*
from tableA a
join tableB b on
case when a.col_A regexp '^USA[0-9]{1}.+$' then substring(a.col_A,1,4) else '' end
= b.col_B
I'm trying to build a SQL statement to retrieve user names in the following order
at first, return the names that start with Arabic letter, then the names that start with English letters, then the names that start with special characters.
then sort each of the three groups in ascending order.
This is my code:
SELECT `name` FROM `user`
order by case when substring(name,1,1) like 'N[أ-ي]' then 1
when substring(name,1,1) like '[a-zA-Z]' then 2
else 3
end
,name
The problem is that the case part always returns 3, and so the statement sorts the names in the default order(special chars first, then English letters then Arabic letters). What is the problem in my query?
You need to use regex, not like... (because you use regular expression)
SELECT `name` FROM `user`
order by case when substring(name,1,1) regexp 'N[أ-ي]' then 1
when substring(name,1,1) regexp '[a-zA-Z]' then 2
else 3
end
,name
Reference: MySQL CASE statement and REGEXP
How to return rows where a column has 2 words (that is, strings separated by a space) in it?
It must be purely using SQL.
SELECT * FROM table WHERE name (has 2 strings in it);
I dont know the names when querying. Its a big dataset. I only have to check if the name contains a spacebar basically (from a comment).
If you want to distinguish names that have two parts from one-part and three-plus-part names, you can use regular expression:
SELECT * FROM my_table WHERE name REGEXP '^[^ ]+[ ]+[^ ]+$'
This regular expression matches when the entire string consists of two non-empty parts containing no spaces, with one or more space separating them.
This perfectly works for me
You can use 'AND' condition and Like Operator with wildcards (%).
SELECT * FROM table_name WHERE name LIKE '%Word1%' AND name LIKE '%Word2%'
How about simply:
...
WHERE [name] LIKE '%Word1%'
AND [name] LIKE '%Word2%'
SELECT * FROM table WHERE concat(' ',name,' ') like '% str1 %'
AND concat(' ',name,' ') like '% str2 %'
The extra blanks are there to separate words.
You can use the following technique
mysql> select length('first name')-length(replace('first name',' ','')) as diff;
+------+
| diff |
+------+
| 1 |
+------+
i.e. get the difference of actual name and the name after replacing space, and if its 1 then you have the value as firstname lastname
So the query may look like
select * from table
where
length(col_name)-length(replace(col_name,' ','')) = 1
Use % between words.
Example:
SELECT * FROM Table WHERE Col LIKE '%word1%word2%'
SELECT * FROM table_name WHERE name LIKE '% %'
Compare comma-separated string in MySQL column where column is also comma separated
For Example:
Id name catid
1 abc 4,5,2
2 bcd 5
3 efg 9,1,7
SELECT * FROM TABLE WHERE catid IN (2,5,6)
Here 2,5,6 I have to compare with the catid value to get the result.
Any Help to get the right out put, I used FIND_IN_SET, but could not make it work for my case
according to your problem you can use LIKE operator instead of IN
SELECT * FROM testchintan WHERE CONCAT(',',catid,',') LIKE '%,5,%'
OR CONCAT(',',catid,',') LIKE '%,2,%' OR CONCAT(',',catid,',') LIKE '%,6,%'
OR YOU can use REGEXP
SELECT *
FROM testchintan
WHERE catid REGEXP '[4,9,5]'
OR
SELECT *
FROM testchintan
WHERE
REPLACE(catid,',','|') REGEXP '[9,7]'
Note that I'm not seriously advocating this as a solution...
SELECT * FROM my_table WHERE FIND_IN_SET(5,catid) OR FIND_IN_SET(2,catid);
In my table I have firstname and last name. Few names are upper case ( ABRAHAM ), few names are lower case (abraham), few names are character starting with ucword (Abraham).
So when i am doing the where condition using REGEXP '^[abc]', I am not getting proper records. How to change the names to lower case and use SELECT QUERY.
SELECT * FROM `test_tbl` WHERE cus_name REGEXP '^[abc]';
This is my query, works fine if the records are lower case, but my records are intermediate ,my all cus name are not lower case , all the names are like ucword.
So for this above query am not getting proper records display.
I think you should query your database making sure that the names are lowered, suppose that name is the name you whish to find out, and in your application you've lowered it like 'abraham', now your query should be like this:
SELECT * FROM `test_tbl` WHERE LOWER(cus_name) = name
Since i dont know what language you use, I've just placed name, but make sure that this is lowered and you should retrieve Abraham, ABRAHAM or any variation of the name!
Hepe it helps!
Have you tried:
SELECT * FROM `test_tbl` WHERE LOWER(cus_name) REGEXP '^[abc]';
I don't know since when, but nowadays MySql REGEXP is case insensitive.
https://dev.mysql.com/doc/refman/5.7/en/pattern-matching.html
You don't need regexp to search for names starting with a specific string or character.
SELECT * FROM `test_tbl` WHERE cus_name LIKE 'abc%' ;
% is wildcard char. The search is case insensitive unless you set the binary attribute for column cus_name or you use the binary operator
SELECT * FROM `test_tbl` WHERE BINARY cus_name LIKE 'abc%' ;
A few valid options already presented, but here's one more with just regex:
SELECT * FROM `test_tbl` WHERE cus_name REGEXP '^[abcABC]';