How can I make SQL case sensitive string comparison on MySQL?

前端 未结 11 2193
温柔的废话
温柔的废话 2020-11-22 02:45

I have a function that returns five characters with mixed case. If I do a query on this string it will return the value regardless of case.

How can I make MySQL stri

相关标签:
11条回答
  • 2020-11-22 03:01

    The answer posted by Craig White has a big performance penalty

    SELECT *  FROM `table` WHERE BINARY `column` = 'value'
    

    because it doesn't use indexes. So, either you need to change the table collation like mention here https://dev.mysql.com/doc/refman/5.7/en/case-sensitivity.html.

    OR

    Easiest fix, you should use a BINARY of value.

    SELECT *  FROM `table` WHERE `column` = BINARY 'value'
    

    E.g.

    mysql> EXPLAIN SELECT * FROM temp1 WHERE BINARY col1 = "ABC" AND col2 = "DEF" ;
    +----+-------------+--------+------+---------------+------+---------+------+--------+-------------+
    | id | select_type | table  | type | possible_keys | key  | key_len | ref  | rows   | Extra       |
    +----+-------------+--------+------+---------------+------+---------+------+--------+-------------+
    |  1 | SIMPLE      | temp1  | ALL  | NULL          | NULL | NULL    | NULL | 190543 | Using where |
    +----+-------------+--------+------+---------------+------+---------+------+--------+-------------+
    

    VS

    mysql> EXPLAIN SELECT * FROM temp1 WHERE col1 = BINARY "ABC" AND col2 = "DEF" ;
    +----+-------------+-------+-------+---------------+---------------+---------+------+------+------------------------------------+
    | id | select_type | table | type  | possible_keys | key           | key_len | ref  | rows | Extra                              |
    +----+-------------+-------+-------+---------------+---------------+---------+------+------+------------------------------------+
    |  1 | SIMPLE      | temp1 | range | col1_2e9e898e | col1_2e9e898e | 93      | NULL |    2 | Using index condition; Using where |
    +----+-------------+-------+-------+---------------+---------------+---------+------+------+------------------------------------+
    enter code here
    

    1 row in set (0.00 sec)

    0 讨论(0)
  • 2020-11-22 03:01

    Excellent!

    I share with you, code from a function that compares passwords:

    SET pSignal =
    (SELECT DECODE(r.usignal,'YOURSTRINGKEY') FROM rsw_uds r WHERE r.uname =
    in_usdname AND r.uvige = 1);
    
    SET pSuccess =(SELECT in_usdsignal LIKE BINARY pSignal);
    
    IF pSuccess = 1 THEN
          /*Your code if match*/
    ELSE
          /*Your code if don't match*/
    
    END IF;
    
    0 讨论(0)
  • 2020-11-22 03:03

    You can use BINARY to case sensitive like this

    select * from tb_app where BINARY android_package='com.Mtime';
    

    unfortunately this sql can't use index, you will suffer a performance hit on queries reliant on that index

    mysql> explain select * from tb_app where BINARY android_package='com.Mtime';
    +----+-------------+--------+------------+------+---------------+------+---------+------+---------+----------+-------------+
    | id | select_type | table  | partitions | type | possible_keys | key  | key_len | ref  | rows    | filtered | Extra       |
    +----+-------------+--------+------------+------+---------------+------+---------+------+---------+----------+-------------+
    |  1 | SIMPLE      | tb_app | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 1590351 |   100.00 | Using where |
    +----+-------------+--------+------------+------+---------------+------+---------+------+---------+----------+-------------+
    

    Fortunately, I have a few tricks to solve this problem

    mysql> explain select * from tb_app where android_package='com.Mtime' and BINARY android_package='com.Mtime';
    +----+-------------+--------+------------+------+---------------------------+---------------------------+---------+-------+------+----------+-----------------------+
    | id | select_type | table  | partitions | type | possible_keys             | key                       | key_len | ref   | rows | filtered | Extra                 |
    +----+-------------+--------+------------+------+---------------------------+---------------------------+---------+-------+------+----------+-----------------------+
    |  1 | SIMPLE      | tb_app | NULL       | ref  | idx_android_pkg           | idx_android_pkg           | 771     | const |    1 |   100.00 | Using index condition |
    +----+-------------+--------+------------+------+---------------------------+---------------------------+---------+-------+------+----------+-----------------------+  
    
    0 讨论(0)
  • 2020-11-22 03:10

    To make use of an index before using the BINARY, you could do something like this if you have large tables.

    SELECT
       *
    FROM
       (SELECT * FROM `table` WHERE `column` = 'value') as firstresult
    WHERE
       BINARY `column` = 'value'
    

    The subquery would result in a really small case-insensitive subset of which you then select the only case-sensitive match.

    0 讨论(0)
  • 2020-11-22 03:15

    http://dev.mysql.com/doc/refman/5.0/en/case-sensitivity.html

    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.

    0 讨论(0)
  • 2020-11-22 03:15

    mysql is not case sensitive by default, try changing the language collation to latin1_general_cs

    0 讨论(0)
提交回复
热议问题