MySQL Where Query using string with special characters - mysql

I have the following query:
SELECT *
FROM (
`teams`
)
WHERE `name` = 'mi equiñerolico'
And the result of this query is:
idteam|name|datet
9|mi equiñerolíco|2012-06-23 12:15:32
As you can see it retrieves a row with the name 'mi equiñerolíco' even though that my Where clause establish that it must be 'mi equiñerolico'.
teams table has utf8_general_ci collation.
How can I solve this ambiguity?

You could use a binary collation to force an accent-sensitve compare:
select *
from teams
where name = 'mi equiñerolico' collate utf8_bin

Related

matching exactly word in utf8 in where clause mysql

I have a query like this :
SELECT * FROM category_keyword WHERE keyword = 'cho'
This query is return result keyword ={ cho , chợ , chờ , chợ ...}. I only want the result is keyword = 'cho' ( not 'chợ, chờ ...') . How can I do?
The collation of table is utf8_unicode_ci
With utf8 collation, cho does equal chờ. If you want to compare as binary:
SELECT * FROM category_keyword WHERE keyword = CONVERT('cho' USING binary)
Change the collation for the column to utf8_bin. This is better than using CONVERT because it allows the use of an index. However, if you sometimes need utf8_bin (exact match) and sometimes need utf8_unicode_ci (for case folding and accent stripping), you are out of luck, performance-wise.

MySQL order incorrect with capitalized letters

I'm trying to order at table with:
select * from my_table order by name
but something goes wrong, since:
IT is listed before Ib
For some reason capitalized letters are seen as more important?
Try this for case insensitive ordering:
SELECT * FROM `my_table` ORDER BY `name` COLLATE 'latin1_general_ci'

How do I perform a case-sensitive search using LIKE?

I'm trying to find records that contain a string of 6 or more alpha-numeric characters in uppercase. Some examples:
PENDING 3RDPARTY CODE27
I'm using the following statement:
SELECT Details
FROM MyTable
WHERE Details LIKE '%[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]%';
This is returning all records that contain any 6-or-more-letter word, regardless of case.
I've added a COLLATE statement:
SELECT Details
FROM MyTable
WHERE Details COLLATE Latin1_General_CS_AS LIKE '%[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]%';
This changes nothing. It still returns records with 6-or-more-letter word, regardless of case.
Just as a test, I tried:
SELECT Details
FROM MyTable
WHERE Details COLLATE Latin1_General_CS_AS LIKE '%pending%';
SELECT Details
FROM MyTable
WHERE Details COLLATE Latin1_General_CS_AS LIKE '%PENDING%';
Both of these worked, returning records containing "pending" and "PENDING" respectively. So the issue seems to by the LIKE claus's pattern matching.
What can I do to perform this case-sensitive search?
Try using COLLATE Latin1_General_BIN rather than COLLATE Latin1_General_CS_AS
Update due to #GeraldSv: Use collation Latin1_General_BIN
SELECT Details
FROM MyTable
WHERE Details
LIKE '%[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]%'
COLLATE Latin1_General_BIN;
You need to place the collation specifier after the string to be matched rather than the column:
SELECT Details
FROM MyTable
WHERE Details
LIKE '%[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]%'
COLLATE Latin1_General_CS_AS;
Update: While my answer above is correct, there is a bug filed at Connect: Case-SENSITIVITY doesn't work when using a range in like with COLLATE Latin1_General_CS_AS which Microsoft have marked as 'By Design".
I verified by using AdventureWorks2008R2 (case insensitive, out of the box default), in the Person.Person table I changed 3 last names ending in 'n' to 'N', and then ran the following queries:
SELECT COUNT(*)
FROM Person.Person
WHERE LastName LIKE '%N' COLLATE Latin1_General_CS_AS
Success. Return 3 rows as expected.
SELECT COUNT(*)
FROM Person.Person
WHERE LastName LIKE '%[N]' COLLATE Latin1_General_CS_AS
Success. Return 3 rows as expected.
SELECT COUNT(*)
FROM Person.Person
WHERE LastName LIKE '%[N-N]' COLLATE Latin1_General_CS_AS
Success. Return 3 rows as expected.
SELECT COUNT(*)
FROM Person.Person
WHERE LastName LIKE '%[M-N]' COLLATE Latin1_General_CS_AS
Fails. Returns 3334 Rows (which is all Lastname's ending in 'n' and 'N')
Update: Thanks to #GeraldSv, this works:
SELECT COUNT(*)
FROM Person.Person
WHERE LastName LIKE '%[M-N]' COLLATE Latin1_General_BIN
I use the following:
SELECT COUNT(*)
FROM Person.Person
WHERE LastName COLLATE Latin1_General_CS_AS != upper(LastName) COLLATE Latin1_General_CS_AS

MySQL query - force case-sensitive with a ORDER BY rand( )

Is it possible to force case-sensitive for a query?
Mine sounds like this:
"SELECT g_path FROM glyphs WHERE g_glyph = :g_glyph ORDER BY rand()"
if g_glyph = r, the result can be R or r and it's not what I expect.
I'm looking for a case-sensitive return.
I googled my issue and I found this solution:
/*Case-sensitive sort in descending order.
In this query, ProductName is sorted in
case-sensitive descending order.
*/
SELECT ProductID, ProductName, UnitsInStock
FROM products
ORDER BY BINARY ProductName DESC;
But the following line doesn't work at all:
"SELECT g_path FROM glyphs WHERE g_glyph = :g_glyph ORDER BY BINARY rand()"
Any Suggestion?
Thank you very much for your help.
The order and equality of characters is defined by the collation. In most cases, a case-insensitive collation is used.
If you need to use a strict, case-sensitive comparison for a specific datum, use the BINARY operator:
mysql> SELECT 'a' = 'A';
-> 1
mysql> SELECT BINARY 'a' = 'A';
-> 0
mysql> SELECT 'a' = 'a ';
-> 1
mysql> SELECT BINARY 'a' = 'a ';
-> 0
So in your case:
SELECT g_path FROM glyphs WHERE BINARY g_glyph = :g_glyph ORDER BY rand()
This is covered in the manual page Case Sensitivity in String Searches.
You need to specify a case sensitive or binary collation.
The default character set and collation are latin1 and latin1_swedish_ci, so nonbinary string comparisons are case insensitive by default. This means that if you search with col_name LIKE 'a%', you get all column values that start with A or a. To make this search case sensitive, make sure that one of the operands has a case sensitive or binary collation. For example, if you are comparing a column and a string that both have the latin1 character set, you can use the COLLATE operator to cause either operand to have the latin1_general_cs or latin1_bin collation:
col_name COLLATE latin1_general_cs LIKE 'a%'
col_name LIKE 'a%' COLLATE latin1_general_cs
col_name COLLATE latin1_bin LIKE 'a%'
col_name LIKE 'a%' COLLATE latin1_bin
If you want a column always to be treated in case-sensitive fashion, declare it with a case sensitive or binary collation. See Section 13.1.14, “CREATE TABLE Syntax”.
The _cs in the collation name stands for "case sensitive".

ensuring search lowercase characters

How do I search lower case in MySQL?
I have the following
$sql = "SELECT * FROM TABLE_NAME WHERE column LIKE '%$search%'";
How do I make sure the values in "column" are matched to lowercase?
You should either set your column's collation to a case-sensitive one, like UTF8_BIN, or make an additional check in the filter:
SELECT *
FROM table_name
WHERE column LIKE '%$search$%'
AND column COLLATE UTF8_BIN = LOWER(column COLLATE UTF8_BIN)
Note that if your collation is case-insensitive, like UTF8_GENERAL_CI, then the following query:
SELECT LOWER('A') = ('A')
will return true. You should explicitly coerce your column to a case-insensitive collation before doing a comparison.
Assuming I'm interpreting correctly, use the MySQL LOWER() function:
$sql = "SELECT * FROM TABLE_NAME WHERE LOWER(column) LIKE '%$search%'";
This will convert everything in column to lowercase before testing it against the search value.