ฉันจะค้นหา (ตัวพิมพ์เล็กและตัวพิมพ์ใหญ่) ในคอลัมน์โดยใช้สัญลักษณ์แทน LIKE ได้อย่างไร


289

ฉันมองไปรอบ ๆ และไม่พบสิ่งที่ฉันเป็นหลังจากนั้นที่นี่ไป

SELECT * FROM trees WHERE trees.`title` LIKE  '%elm%'

มันใช้งานได้ดี แต่ไม่ใช่ถ้าต้นไม้มีชื่อว่า Elm หรือ ELM ฯลฯ ...

ฉันจะทำให้ตัวพิมพ์เล็กและตัวพิมพ์เล็กของ SQL ไม่ได้สำหรับการค้นหาไวด์การ์ดนี้ได้อย่างไร

ฉันใช้ MySQL 5 และ Apache


3
หากคุณสะดุดในหน้านี้ แต่การตั้งค่า MySql ของคุณทำงานกับแบบสอบถามนี้สำหรับ Elm หรือ ELM และคุณต้องการให้คำนึงถึงตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ดูBINARYที่นี่: stackoverflow.com/questions/7857669/ …
joshuahedlund

มันไม่ได้ขึ้นอยู่กับการเรียงฟิลด์ / ตาราง? เช่น 'ut8_general_CI'
Yousha Aleayoub

วิธีการใช้งานมัน sequlize แบบสอบถามโหนด?
Ashh

MySQL likeควรคำนึงถึงตัวพิมพ์เล็กและตัวพิมพ์ใหญ่โดยค่าเริ่มต้น
Marko Bonaci

คำตอบ:


281
SELECT  *
FROM    trees
WHERE   trees.`title` COLLATE UTF8_GENERAL_CI LIKE '%elm%'

ที่จริงแล้วถ้าคุณเพิ่มCOLLATE UTF8_GENERAL_CIเข้าไปในคำจำกัดความของคอลัมน์ของคุณคุณก็สามารถละเว้นเทคนิคเหล่านี้ทั้งหมด: มันจะทำงานโดยอัตโนมัติ

ALTER TABLE trees 
 MODIFY COLUMN title VARCHAR(…) CHARACTER 
 SET UTF8 COLLATE UTF8_GENERAL_CI. 

สิ่งนี้จะสร้างดัชนีใด ๆ ในคอลัมน์นี้อีกครั้งเพื่อให้สามารถใช้กับแบบสอบถามได้โดยไม่ต้องนำหน้า '%'


34
ที่จริงแล้วถ้าคุณเพิ่มCOLLATE UTF8_GENERAL_CIเข้าไปในคำจำกัดความของคอลัมน์ของคุณคุณก็สามารถละเว้นเทคนิคเหล่านี้ทั้งหมด: มันจะทำงานโดยอัตโนมัติ ALTER TABLE trees MODIFY COLUMN title VARCHAR(…) CHARACTER SET UTF8 COLLATE UTF8_GENERAL_CI. สิ่งนี้จะสร้างดัชนีใด ๆ ในคอลัมน์นี้อีกครั้งเพื่อให้สามารถใช้สำหรับการสืบค้นได้โดยไม่ต้องนำหน้า '%'
Quassnoi

1
เปลี่ยนตารางต้นไม้แก้ไขคอลัมน์ชื่อ VARCHAR (... ) นี่เป็นวิธีที่ดีที่สุดขอบคุณมาก ... ให้ sql ทำงาน
David Morrow

10
เตือนความจำที่เป็นมิตรว่านี่คือคำตอบของ MySQL หากคุณใช้ PostgreSQL แล้ว ILike เป็นคำตอบสำหรับคำถามข้างต้น
Steve

2
@RajanRawal: โปรดโพสต์คำถามของคุณเป็นคำถามไม่ใช่ความคิดเห็น ขอบคุณ
Quassnoi

1
นี่คือคำตอบที่ถูกต้องตราบใดที่การเรียงหน้าดั้งเดิมของคุณเป็นแบบทั่วไปไม่ใช่ bin
greenoldman

261

ฉันมักจะแก้ปัญหานี้โดยใช้ที่ต่ำกว่า:

SELECT * FROM trees WHERE LOWER( trees.title ) LIKE  '%elm%'

47
และทำให้เสียการใช้ดัชนี
สามัญสำนึกของคุณ

3
MySQL 5 มีตัวดำเนินการ ILIKE หรือไม่
Luke Maurer

27
แม้ว่าการค้นหา %% มันไม่สำคัญหรอก :)
สามัญสำนึกของคุณ

5
@Col - เป็นที่ยอมรับว่านี่เหมาะน้อยสำหรับคอลัมน์ที่จัดทำดัชนี แต่จะใช้ได้กับโครงสร้างที่มีอยู่แล้ว ฉันยังพบว่าการค้นหาแบบตัวพิมพ์เล็กและตัวพิมพ์ใหญ่มักจะอยู่ในคอลัมน์ที่ไม่ได้จัดทำดัชนีอยู่แล้ว
cwallenpoole

1
การเรียงหน้าเริ่มต้นคือ CI แล้ว ดังนั้นปัญหาจริงไม่ได้อยู่ในคำถามนี้ แต่มันยังคงเป็นคำตอบที่สมบูรณ์แบบดังนั้น
สามัญสำนึกของคุณ

48

ความไวตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ถูกกำหนดในการตั้งค่าการเรียงคอลัมน์ / ตาราง / ฐานข้อมูล คุณสามารถทำแบบสอบถามภายใต้การเปรียบเทียบที่เฉพาะเจาะจงด้วยวิธีดังต่อไปนี้:

SELECT *
FROM trees
WHERE trees.`title` LIKE '%elm%' COLLATE utf8_general_ci

เช่น

(แทนที่utf8_general_ciด้วยการเปรียบเทียบสิ่งที่คุณพบว่ามีประโยชน์) _ciยืนสำหรับกรณีตาย


1
ใน MySQL 5.6 ฉันได้รับข้อผิดพลาด 1273 (HY000): ไม่ทราบเรียง: 'utf_general_ci' ฉันเดาว่าการเปรียบเทียบนี้ถูกลบออกจาก MySQL หรือไม่ utf8_general_ciทำงานได้ดีแม้ว่า
Mark Amery

1
มีปัญหาเดียวกัน คุณต้องแก้ไขCOLLATEหรือทำกลอุบายอย่างง่าย ๆ เช่นนี้ ( LOWER()ทั้งสองสายก่อนเปรียบเทียบ)
Menelaos Kotsollaris

ใน MySQL 5.6+ หรือ MariaDB 10+ คุณเพียงแค่ต้องจัดเตรียมคำสั่ง COLLATE ก่อนเงื่อนไขของคุณ ดังนั้นสิ่งนี้จึงใช้ได้:SELECT * FROM products WHERE name COLLATE utf8_general_ci LIKE 'AB47TU';
เตอร์

41

นี่คือตัวอย่างของแบบสอบถาม LIKE ที่เรียบง่าย:

SELECT * FROM <table> WHERE <key> LIKE '%<searchpattern>%'

ตอนนี้ตัวพิมพ์เล็กและใหญ่โดยใช้ LOWER () func:

SELECT * FROM <table> WHERE LOWER(<key>) LIKE LOWER('%<searchpattern>%')

3
อันที่จริงนี่เป็นทางออกที่ดีโดยเฉพาะอย่างยิ่งเมื่อคุณประสบกับCOLLATEปัญหารูปแบบ
Menelaos Kotsollaris

27

เพียงใช้:

"SELECT * FROM `trees` WHERE LOWER(trees.`title`) LIKE  '%elm%'";

หรือใช้

"SELECT * FROM `trees` WHERE LCASE(trees.`title`) LIKE  '%elm%'";

ฟังก์ชั่นทั้งสองทำงานเหมือนกัน


15

ฉันทำอะไรแบบนั้น

รับค่าเป็นตัวพิมพ์เล็กและ MySQL ทำส่วนที่เหลือ

    $string = $_GET['string'];
    mysqli_query($con,"SELECT *
                       FROM table_name
                       WHERE LOWER(column_name)
                       LIKE LOWER('%$string%')");

และสำหรับ MySQL PDO Alternative:

        $string = $_GET['string'];
        $q = "SELECT *
              FROM table_name
              WHERE LOWER(column_name)
              LIKE LOWER(?);";
        $query = $dbConnection->prepare($q);
        $query->bindValue(1, "%$string%", PDO::PARAM_STR);
        $query->execute();

6

ฉันคิดว่าคำค้นหานี้จะทำการค้นหาแบบตัวพิมพ์เล็กและตัวพิมพ์ใหญ่:

SELECT * FROM trees WHERE trees.`title` ILIKE '%elm%';

1
ฉันได้รับข้อผิดพลาดทางไวยากรณ์ของ mysql 5.5 ขณะที่ใช้ ILIKE ในการสืบค้นของฉัน
Steel Brain

18
สิ่งนี้ใช้ได้กับ PostgreSQL เท่านั้น ไม่ใช่ MySQL postgresql.org/docs/current/static/functions-matching.html
Martin Tournoij

ตามที่ระบุไว้แล้วคำถามนั้นเกี่ยวกับ MySQL และคำตอบนั้นเกี่ยวกับ PostgreSQL และแน่นอนว่านรกไม่สามารถทำงานกับ MySQL ได้ ฉันทำไม่ได้ลงคะแนนเสียงได้ แต่ไม่สามารถช่วยเหลือสงสัยที่ขึ้นมาจากคะแนนโหวต ...
silverdr

5

ใช้ ILIKE

SELECT * FROM trees WHERE trees.`title` ILIKE '%elm%';

มันได้ผลสำหรับฉัน !!


9
MySQL ไม่รองรับ ILIKE
ttarchala

3
ใช้งานได้กับ PostgreSQL คำถามคือเกี่ยวกับ MySQL
Telmo Trooper

4

คุณไม่จำเป็นต้องไปที่ALTERโต๊ะใด ๆ เพียงใช้คำค้นหาต่อไปนี้ก่อนที่จะมีSELECTคำค้นหาจริงที่คุณต้องการใช้สัญลักษณ์แทน:

    set names `utf8`;
    SET COLLATION_CONNECTION=utf8_general_ci;
    SET CHARACTER_SET_CLIENT=utf8;
    SET CHARACTER_SET_RESULTS=utf8;

2
นี่เป็นความเห็นที่ประเมินต่ำมาก มันตอบคำถามโดยทั่วไป ฉันคิดว่าไวยากรณ์ตารางการเปลี่ยนแปลงมีความสำคัญเช่นกันเนื่องจากคำถามอาจต้องการการเปรียบเทียบที่ จำกัด เพียงคอลัมน์เดียวเท่านั้น
Brian Chrisman

1

ใน mysql 5.5 เช่นโอเปอเรเตอร์นั้นไม่มีความรู้สึก ... ดังนั้นหากหุบเขาของคุณคือ elm หรือ ELM หรือ Elm หรือ eLM หรืออื่น ๆ และคุณใช้เช่น '% elm%' มันจะแสดงรายการค่าที่ตรงกันทั้งหมด

ฉันไม่สามารถพูดเกี่ยวกับ mysql รุ่นก่อนหน้าได้

หากคุณไปที่ Oracle เช่นทำงานแบบตรงตามตัวพิมพ์ใหญ่ - เล็กดังนั้นหากคุณพิมพ์เช่น '% elm%' ระบบจะดำเนินการเฉพาะกรณีนี้เท่านั้นและไม่สนใจตัวพิมพ์ใหญ่ ..

แปลก แต่นี่เป็นวิธี :)


สิ่งนี้ไม่เป็นความจริงทั้งหมด มันทำงานในลักษณะนั้นก็ต่อเมื่อมีการตั้งค่าการเปรียบเทียบ*_ciซึ่งย่อมาจาก "case insensitive" เนื่องจากนี่เป็นค่าเริ่มต้นสำหรับชุดอักขระที่รองรับทั้งหมด (ปัญหาshow character set;ในการตรวจสอบ) - คำตอบนั้นเป็นจริงเพียงบางส่วน :-) เหตุผลเท่านั้นที่ไม่ถูกต้อง ไม่ใช่ตัวดำเนินการที่ไม่คำนึงถึงขนาดตัวพิมพ์ แต่เป็นตัวเปรียบเทียบที่เป็นค่าเริ่มต้น
silverdr

ใช่ฉันเห็นด้วยกับคุณ มันขึ้นอยู่กับตัวละครและยังถ้าคุณอยู่ในการผลิตด้วยตัวละคร * _ci ตัวเลือกเท่านั้นคือการใช้ไบนารีก่อนที่ข้อ
user21546

1
SELECT name 
       FROM gallery 
       WHERE CONVERT(name USING utf8) LIKE _utf8 '%$q%' 
       GROUP BY name COLLATE utf8_general_ci LIMIT 5 

แกลเลอรี่คือชื่อตารางชื่อคือคอลัมน์ในตาราง
user4189641

2
โปรดเพิ่มคำอธิบายบางส่วนของรหัสของคุณซึ่งแสดงว่ามันทำอะไรและจะช่วยอย่างไร - สิ่งนี้จะช่วยผู้อื่นในอนาคต
Our Man in Bananas

0

คุณต้องตั้งค่าการเข้ารหัสและการจัดเรียงที่เหมาะสมสำหรับตารางของคุณ

การเข้ารหัสตารางจะต้องสะท้อนการเข้ารหัสข้อมูลจริง การเข้ารหัสข้อมูลของคุณคืออะไร?

หากต้องการดูการเข้ารหัสตารางคุณสามารถเรียกใช้คิวรีได้ SHOW CREATE TABLE tablename


0

เมื่อฉันต้องการพัฒนาการค้นหาตัวพิมพ์เล็กและตัวพิมพ์เล็กฉันจะแปลงสตริงทุกตัวให้เป็นตัวพิมพ์เล็กเสมอก่อนทำการเปรียบเทียบ


0

คุณสามารถใช้วิธีการดังต่อไปนี้

 private function generateStringCondition($value = '',$field = '', $operator = '', $regex = '', $wildcardStart = '', $wildcardEnd = ''){
        if($value != ''){
            $where = " $field $regex '$wildcardStart".strtolower($value)."$wildcardEnd' ";

            $searchArray = explode(' ', $value);

            if(sizeof($searchArray) > 1){

                foreach ($searchArray as $key=>$value){
                    $where .="$operator $field $regex '$wildcardStart".strtolower($value)."$wildcardEnd'";
                }

            }

        }else{
            $where = '';
        }
        return $where;
    }

ใช้วิธีนี้เหมือนด้านล่าง

   $where =  $this->generateStringCondition($yourSearchString,  'LOWER(columnName)','or', 'like',  '%', '%');
  $sql = "select * from table $where";

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.