MySQL Collate Latin1_General_CI_AI Problem - mysql

I have the following select statement where I'm trying to search for a players first and last name that may contain accents in it.
$sql = "
SELECT * FROM player
WHERE player.player_first LIKE '%$first%'
AND player.player_last LIKE '%$last%'
";
I adding COLLATE Latin1_General_CI_AI after before both of the LIKE clauses, but that didn't work and returned errors.
Any help would be appreciated.

According to MySQL doc the collation Latin1_General_CI_AI does not exists.
Try latin1_general_ci instead.

Related

Mysql collation error on laravel query, related to search parameter

My search query has COLLATE utf8mb4_bin which is necessary to differentiate between european characters and non-european character, for example a vs ä.
If I run the query with hard coded search term, it works in phpmyadmin, and it works on this fiddle: db-fiddle. You can see that the table has CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci.
But on this other fiddle site ( sqlfiddle), the same query gives the error:
COLLATION 'utf8mb4_bin' is not valid for CHARACTER SET 'utf8'
And in laravel, if I run the query with hard coded search term, it works without error, but if I use a parameter I get this error:
SQLSTATE[42000]: Syntax error or access violation: 1253 COLLATION 'utf8mb4_bin' is not
valid for CHARACTER SET 'binary'
So it is very strange. Here is the laravel query with bound parameters which produces the above error:
$query_events = "SELECT e.id, e.title, e.location,e.event_at, e.content as content,
e.limited_participants,e.max_participants,associations.name,
CONCAT(:url,'/events/', e.id) AS permalink,
(SELECT COUNT(*) FROM event_participants evp WHERE evp.event_id = e.id)
AS participants
FROM events AS e
LEFT JOIN associations ON e.association_id = associations.id
WHERE CONCAT(e.title ,e.location ,e.content ,associations.name )
LIKE :search
COLLATE utf8mb4_bin
ORDER BY e.event_at
DESC
LIMIT 5";
$results['events'] = DB::select($query_events,[
'url' => $url,
'search' => '%' . $search . '%'
]);
If I remove COLLATE utf8mb4_bin, there is no error but european/non-eurpoean letters are mixed up in the search results. If I hard code some search parameter (like in the fiddles) and comment out the 'search' property in the array, the query works as it should, giving the right results.
I use xampp and the mysql version is 5.7.22 according to phpmyadmin.
So I need to use that collation and need to be able to use a search parameter, but how do I avoid this error??
Plan A: Preface the query with
SET NAMES utf8mb4;
Plan B: change the CHARACTER SET of the literal:
LIKE _utf8mb4"%oteborg%"

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.

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

Searching for a codes in a mysql database

I have a database that stores a large number of codes, these codes are used to validate submission of a form. When ever i run the following query i get zero rows back
SELECT * FROM `codes` WHERE `voucher` = 'JTBLYNQ9HA'
but when i run the following query it bring back the single row with the code in it.
SELECT * FROM `codes` WHERE `voucher` LIKE CONVERT( _utf8 '%JTBLYNQ9HA%' USING latin1 ) COLLATE latin1_swedish_ci LIMIT 0 , 30
What am i doing wrong which causes the first query to fail or should is it best practise to use the second query?
Thanks for the help
The two queries are not equivalent. The first one is looking for a code whose voucher is exactly "JTBLYNQ9HA", the second one is looking for a code whose voucher contains that string (for instance, "ABCDEFGJTBLYNQ9HAHIJKLM").
The character set conversion and COLLATE are almost certainly irrelevant.

MySQL DB selects records with and without umlauts. e.g: '.. where something = FÖÖ'

My Table collation is "utf8_general_ci". If i run a query like:
SELECT * FROM mytable WHERE myfield = "FÖÖ"
i get results where:
... myfield = "FÖÖ"
... myfield = "FOO"
is this the default for "utf8_general_ci"?
What collation should i use to only get records where myfield = "FÖÖ"?
SELECT * FROM table WHERE some_field LIKE ('%ö%' COLLATE utf8_bin)
A list of the collations offered by MySQL for Unicode character sets can be found here:
http://dev.mysql.com/doc/refman/5.0/en/charset-unicode-sets.html
If you want to go all-out and require strings to be absolutely identical in order to test as equal, you can use utf8_bin (the binary collation). Otherwise, you may need to do some experimentation with the different collations on offer.
For scandinavian letters you can use utf8_swedish_ci fir example.
Here is the character grouping for utf8_swedish_ci. It shows which characters are interpreted as the same.
http://collation-charts.org/mysql60/mysql604.utf8_swedish_ci.html
Here's the directory listing for other collations. I'm no sure which is the used utf8_general_ci though. http://collation-charts.org/mysql60/