How to perform case insensitive ORDER BY in mysql? - mysql

I want to perform case-insensitive ORDER BY in MySQL.
I have the data in my database like
A, C, b, e, D etc
I'm getting the result as
A, C, D, b, e
But, I want the result as
A, b, C, D, e
How can I get that?

Choose a case-insensitive collation
select * from your_table
order by your_column COLLATE utf8_general_ci
That way indexes still work and the query is fast.

You can use
Select col
from myTable
order by lower(col)
That way it will compare all by lower values.
as #juergen d commented this will void indexes and therefor perfom slowly

There (at least) 3 solutions. Two (LOWER() and ORDER BY .. COLLATE ..) have already been given. Here is a third.
If the COLLATION of the column in question is changed to be some ..._ci collation, then the ORDER BY will do what you want without any special syntax in the query, itself.
See the reference manual on "collation".
PS: Changing the column definition to a suitable collation is more efficient than LOWER or the COLLATE clause, especially for large tables.

Use utf8_unicode_ci or utf8mb4_0900_ai_ci in your case. I suggest utf8mb4_0900_ai_ci because it has more characters.
SELECT * FROM <table> ORDER BY <column> COLLATE utf8mb4_0900_ai_ci;
If you have no reason to choose a schema collation, select utf8mb4_0900_ai_ci

Related

MYSQL query did not order results mix char

I have a table with id, surname etc., when I query order by surname I obtain something like this
A, B, C,... V, Z, Ć, Č, Č, Đ ...
where slavian char are ordered after finished western european alphabet
Mysql connection is set in utf-8. query is
SELECT * FROM table ORDER BY SURNAME ASC
how can i obtain an unique order like
A, B, C, Ć, Č, Č, Đ... V, Z
Thanks
in this case you need to define your own Alphabet (or Order). To do so you can follow the answer to this question.
Hopefully it works with non-ascii signs.
What you need is to use proper collation, which provides necessary info about ordering strings. Here's how to use collate keyword:
SELECT * FROM table ORDER BY SURNAME COLLATE latin1_german2_ci
Here I used latin1_german2_ci as an example, find collation that matches your requirements.
Supported Character Sets and Collations

Sorting a MySQL Query ignoring case

Duh right off the bat you'd think, "use ORDER BY and then the column" but I have values of:
A
Z
B
a
z
And when I sort them using this query:
SELECT * FROM Diaries ORDER BY title ASC;
I then get this:
A
B
Z
a
z
When I want to get something like this, first issue:
A
a
B
Z
z
I had the same sorting issue else where, second issue, but I was able to fix it with this: By temporarily putting all characters in lowercase
for (NSString *key in [dicGroupedStories allKeys]) {
[dicGroupedStories setValue: [[dicGroupedStories objectForKey: key] sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
NSString *stringA = [[a objectStory_title] lowercaseString];
NSString *stringB = [[b objectStory_title] lowercaseString];
return [stringA compare: stringB];
}] forKey: key];
}
Only reason why I don't use this Comparator to sort my first issue is bc I don't want to execute my query then sort them then use the array.
Question: I want to know if there's a way to sort them how I want, like I did in my second issue, in a SQL query
objects id a and id b are arrays that contain other objects like title, date created, description, etc. objectDiary_title returns a NSString
In SQL, you can use the lower() or upper() functions in the order by:
ORDER BY lower(Diaries), diaries
You can use COLLATE with xxx_ci where ci means case insensitive. For example:
SELECT * FROM Diaries ORDER BY title COLLATE 'latin1_general_ci' ASC;
There's more information regarding case sensitivity in MySQL here: https://dev.mysql.com/doc/refman/5.0/en/case-sensitivity.html. It's useful for doing searches and comparisons as well.
Use a case-insensitive collation, such as:
ORDER BY Diaries COLLATE utf8_unicode_ci ;
However, changing collation on-the-fly, like any convertion on-the-fly, makes the query unable to use an index (which is acceptable if the data set to be sorted is small enough).
If performance is an issue then you had better reindex the column with the target collation:
ALTER TABLE MODIFY COLUMN Diaries VARCHAR(10) COLLATE utf8_unicode_ci ;
ORDR BY will then be case insensitive by defaut and can use an index on this column.
utf8_unicode_ci is just an example. Just make sure you use a collation *_ci (for Case-Insensitive) which is compatible with the column's encoding

MySQL wrong order of UTF-8 words

When I add UTF-8 words to a table column, and execute an ordered SELECT, the sort order is wrong. On DESC sort, the order is correct but on ASC sort, the order is wrong. How to fix that? Let me explain on example. Lets have a mysql table with Slovak collate:
CREATE TABLE IF NOT EXISTS test (
aaa varchar(255) CHARACTER SET utf8 COLLATE utf8_slovak_ci NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_slovak_ci;
Now lets insert some values with UTF-8 words:
INSERT INTO test (aaa) VALUES
('Leco'),
('Lečo'),
('Ledo'),
('Chovatelstvo'),
('Chovateľstvo')
Here is Slovak alphabet explained, you can see which letters are after which other letters: http://en.wikipedia.org/wiki/Slovak_orthography
Now when I select with order, I expect to get the following result:
SELECT aaa FROM test ORDER BY aaa ASC
Chovatelstvo
Chovateľstvo
Leco
Lečo
Ledo
And I also expect the exactly opposite order for DESC. But here is what I get in fact:
SELECT aaa FROM test ORDER BY aaa ASC
Chovateľstvo
Chovatelstvo
Leco
Lečo
Ledo
and DESC:
SELECT aaa FROM test ORDER BY aaa DESC
Ledo
Lečo
Leco
Chovateľstvo
Chovatelstvo
You can see there
Chovateľstvo
Chovatelstvo
is always in the given order regardless of ASC or DESC. I noticed that if I insert the rows in opposite order, it may end up as
Chovatelstvo
Chovateľstvo
meaning that the actual order is opposite, but again is the same for ASC and DESC. As like if mysql considered those two letters 'l' and 'ľ' as equal.
I tried this with some older version of MySQL, as well as newest version of MariaDB on another server, the result is the same.
Any idea what causes that and how to fix it?
In both the utf8_slovak_ci and utf8_general_ci collations, the letter ľ and the letter l are considered the same.
You can see this by observing that this query returns true (1)
select _utf8 'Chovateľstvo' collate utf8_slovak_ci = _utf8 'Chovatelstvo'
The designers of that collation obviously believe that ľ and l belong together in the dictionary. The only collations I can find that do not do that are latin2_hungarian_ci and cp1250_czech_cs. But to use either one of those you'll have to change your character set choice.
If you must have them be different, you could try the utf8_bin collation. But that will be entirely case sensitive.
The way ORDER BY works is basically correct for the rules in the collation.
Maybe there's a defect in the collation? You could submit a defect report to the MySql team at https://bugs.mysql.com/

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/

Mysql search case insensitive

I'm having problems searching in multiple tables for different values. When I search for "paul" I get nothing, but if I search for "Paul" I get the corresponding persons for orders with the name Paul.
$get_orders = mysql_query("
SELECT
co.id, co.final_id, co.shop_id, co.customer_id, co.payment_type, co.payment_currency, co.billing_email, co.billing_first_name, co.billing_last_name, co.delivery_first_name, co.delivery_last_name, UNIX_TIMESTAMP(co.order_created) AS order_created, c.email, s.site_name,
MATCH(co.final_id, co.billing_first_name, co.billing_last_name, co.delivery_first_name, co.delivery_last_name, co.order_created)
AGAINST ('$match_against' IN BOOLEAN MODE) AS score
FROM customer_orders AS co
LEFT JOIN customers AS c ON c.id = co.customer_id
LEFT JOIN shops AS s ON s.id = co.shop_id WHERE co.status = '{$os}'
ORDER BY score DESC
LIMIT $offset,$views_page") or die(mysql_error());
I've search all over for a solution to this problem. I've tried using UPPER, changing the database collation from utf8_general_ci to utf8_bin (binary) but my problem still remains unsolved..
All suggestions are appreciated..
Regards
from the mysql manual:
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:
see: mysql case sensitivity
See http://bugs.mysql.com/bug.php?id=22343
From my understanding, make sure everything is a string if you want to search for a string.
Also, switch charset back to case-insensitive. No need for it to be binary.