Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LIKE case-insensitive for not English letters

I want to retrieve rows whose TITLE field meets some pattern (case-insensitive), and this field contains only non-English letters.

I tried this:

SEARCH * FROM TABLE_NAME WHERE UPPER(column_name) LIKE UPPER('%pattern%');

However, this doesn't work, may be because the table contains only non-English letters.

UPDATE:

Example:

SELECT * FROM PartnersTable WHERE UPPER(TitleColumn) LIKE UPPER('%pattern%');

Where:

TitleColumn may contain "Газпром", "Лукойл", "Йотафон", "Мечта ювелира",

pattern may contain "газ", "Ювелир" etc.

like image 503
Leonid Semyonov Avatar asked Mar 12 '14 06:03

Leonid Semyonov


People also ask

Is like case-insensitive?

LIKE performs case-insensitive substring matches if the collation for the expression and pattern is case-insensitive. For case-sensitive matches, declare either argument to use a binary collation using COLLATE , or coerce either of them to a BINARY string using CAST .

What is case-insensitive example?

Example of case-insensitivity:The email address may be entered as is or as [email protected], as it will be validated in both cases. In the case of passwords, a case-sensitive login process allows users to create more complex credentials by combining uppercase and lowercase letters, therefore reinforcing security.

What are case-sensitive letters?

adjective. If a written word such as a password is case-sensitive, it must be written in a particular form, for example using all capital letters or all small letters, in order for the computer to recognize it. [computing]

How do you make a case-insensitive query?

SQL Case insensitivity is to use the query statements and the keywords tables and columns by specifying them in capital or small letters of alphabets. SQL keywords are by default set to case insensitive that means that the keywords are allowed to be used in lower or upper case.


2 Answers

I tried it with using COLLATE NOCASE added to the column definition. If you are able to do it, then this is the way to go.

What I tested:

CREATE TABLE PartnersTable 
    (`id` , `TitleColumn` COLLATE NOCASE )
;

Added same data as in your question:

INSERT INTO PartnersTable
    (`id`, `TitleColumn`)
VALUES
 (1, 'Газпром'), (2, 'Лукойл'), (3, 'Йотафон'), (4, 'Мечта ювелира')
;

Then tried to select it:

select *
from PartnersTable
where TitleColumn like '%Ювелир%'

It works.

Demo here: http://sqlfiddle.com/#!7/ae8f8/2

Edit: You can also use it with without UPPER. By default LIKE is case insensitive. As per documentation:

Any other character matches itself or it's lower/upper case equivalent (i.e. case-insensitive matching). (A bug: SQLite only understands upper/lower case for ASCII characters. The LIKE operator is case sensitive for unicode characters that are beyond the ASCII range. For example, the expression 'a' LIKE 'A' is TRUE but 'æ' LIKE 'Æ' is FALSE.)."

Demo here: http://sqlfiddle.com/#!7/c9b5d/1

like image 140
Michał Szkudlarek Avatar answered Oct 20 '22 04:10

Michał Szkudlarek


The code is not working because UPPER is working for only ASCII characters(link). To solve this I implemented User-Defined function with BindFunction for .NET as below.

// for System.Data.SQLite
connection.BindFunction(
    new SQLiteFunctionAttribute("myupper", 1, FunctionType.Scalar),
    (Func<object[], object>)((object[] args) => ((string)((object[])args[1])[0]).ToUpper()),
    null);
        
// for Microsoft.Data.Sqlite
connection.CreateFunction(
    "myupper",
    (string arg) => (arg).ToUpper());

var command = connection.CreateCommand();
command.CommandText =
@"
    SELECT *
    FROM PartnersTable 
    WHERE MYUPPER(TitleColumn) LIKE MYUPPER('%pattern%')
";
      
command.ExecuteQuery()

However it takes longer to execute the query.

Following links might help too

https://docs.microsoft.com/en-us/dotnet/standard/data/sqlite/user-defined-functions https://docs.microsoft.com/en-us/dotnet/standard/data/sqlite/compare

like image 45
kyo Avatar answered Oct 20 '22 04:10

kyo