SQL regex works the wrong way - mysql

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

Related

SQL select values that contain numbers only

Im looking to select only valid number values from table (ean, gtin, upc or barcode)
What is the difference between the 2 statements, as they give me different results.
select count(*) from catalogue where barcode NOT REGEXP '^[0-9]+$';
select count(*) from catalogue where barcode NOT LIKE '%[0-9]%';
Regards
This logic in MySQL:
where barcode NOT REGEXP '^[0-9]+$';
chooses any barcode that is does not consist only of digits.
This logic in MySQL:
where barcode NOT LIKE '%[0-9]%';
chooses any barcode that does not have the four characters '[',, '0', '-', and ']' adjacent to each other in that order in the string.
In other words, LIKE does not recognize character classes in MySQL.
You can also write the logic to identify non-numbers as:
where barcode REGEXP '[^0-9]'
That is, it contains a character that is not a digit.

MySQL- Output an "other" column based on multiple columns

I am using MySQL REGEXP to assign reviews into different topics and output them into separate columns. The problem is- some reviews may not get assigned to any topic, which is why I need an "Other" column. How do I modify the query below to achieve that?
SELECT
text,
text REGEXP 'keywords' AND text REGEXP 'other keywords' AND .... AS Cleanliness,
text REGEXP 'keywords' AND text REGEXP 'other keywords' AND .... AS Restaurant,
text REGEXP 'keywords' AND text REGEXP 'other keywords' AND .... AS Wifi,
FROM review_table;
Note that a review can belong to multiple topics.
The end result should look like this:
One solution would be create anoter REGEXP expression that represents the negation of all other expressions. But that can quickly become tedious to maintain.
Another option is to just wrap the query and analyze the results in the outer query to generate the additional column. This should be as simple as:
SELECT x.*, (Cleanliness + Food + Wifi = 0) AS Other
FROM (
--- original query
) x
Tip: in MySQL, the return value of a condition expression is 1 on success and 0 on failure. This means that this expression:
CASE
WHEN review REGEXP 'relevant keywords'
AND review REGEXP 'additional keywords if necessary'
THEN 1
ELSE 0
END AS 'Cleanliness'
Can also be written:
(
review REGEXP 'relevant keywords'
AND review REGEXP 'additional keywords if necessary'
) AS 'Cleanliness'
I think we can use the NOT(expression) command
CASE
WHEN review NOT (REGEXP 'relevant keywords'
AND review REGEXP 'additional keywords if necessary' )
THEN 1
ELSE 0
END AS 'Irrelevant'
Reference: https://dev.mysql.com/doc/refman/5.7/en/regexp.html
Related: negate regex pattern in mysql

SELECT Mysql with combination of two where

I want select 2 Rows from the mysql table with additional "LIKE" and "AND" clauses..
Wit like clause I want to find only word starting with "a%"..
But I can't find the syntax error. Can you give me some hints.??
SELECT word,description
FROM word
WHERE(`language` = CONVERT( _utf8 'Tedi' USING armscii8 ) AND like 'a%') AND `visible` =1
many thanks in advance.
Regards,
Koko
The syntax error is a missing expression before the LIKE comparison operator.
We'll have to guess what expression you wanted to do the comparison operation on, so I'll just choose the first column from the SELECT list, to demonstrate:
SELECT w.word
, w.description
FROM word w
WHERE w.language = CONVERT( _utf8 'Tedi' USING armscii8 )
AND w.word LIKE 'a%'
AND w.visible = 1
The predicates in the WHERE clause specify the criteria that a row has to satisfy before it will be returned, it doesn't care whether that's zero rows, two rows or a brazilian rows.

Alternative to LIKE clause in Mysql

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.

MySQL regex query case insensitive

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]';