Bagaimana saya bisa mencari (case-insensitive) di kolom menggunakan LIKE wildcard?

289

Saya melihat-lihat beberapa dan tidak menemukan apa yang saya cari jadi begini.

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

Ini berfungsi dengan baik, tetapi tidak jika pohon tersebut dinamai Elm atau ELM dll ...

Bagaimana cara membuat SQL case peka untuk pencarian wild-card ini?

Saya menggunakan MySQL 5 dan Apache.

David Morrow
sumber
3
Jika Anda menemukan halaman ini tetapi pengaturan MySql Anda DO bekerja pada permintaan ini untuk Elm atau ELM dan Anda INGIN peka terhadap huruf besar-kecil, lihat BINARYseperti di sini: stackoverflow.com/questions/7857669/…
joshuahedlund
Tidakkah ini tergantung pada bidang / tabel collation? seperti 'ut8_general_CI'
Yousha Aleayoub
Bagaimana cara menggunakannya sequlize node query?
Ashh
MySQL likeharus case-insensitive secara default.
Marko Bonaci

Jawaban:

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

Sebenarnya, jika Anda menambah COLLATE UTF8_GENERAL_CIdefinisi kolom Anda, Anda bisa menghilangkan semua trik ini: itu akan bekerja secara otomatis.

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

Ini juga akan membangun kembali indeks apa pun pada kolom ini sehingga dapat digunakan untuk kueri tanpa memimpin '%'

Quassnoi
sumber
34
Sebenarnya, jika Anda menambah COLLATE UTF8_GENERAL_CIdefinisi kolom Anda, Anda bisa menghilangkan semua trik ini: itu akan bekerja secara otomatis. ALTER TABLE trees MODIFY COLUMN title VARCHAR(…) CHARACTER SET UTF8 COLLATE UTF8_GENERAL_CI. Ini juga akan membangun kembali indeks apa pun pada kolom ini sehingga dapat digunakan untuk kueri tanpa memimpin '%'.
Quassnoi
1
ALTER TABUNG pohon MODIFY COLUM title VARCHAR (...) ini sepertinya cara terbaik, terima kasih banyak ... biarkan sql melakukan pekerjaannya
David Morrow
10
Pengingat ramah bahwa ini adalah jawaban mysql. Jika Anda menggunakan PostgreSQL, ILike adalah solusi untuk pertanyaan di atas.
Steve
2
@RajanRawal: kirimkan pertanyaan Anda sebagai pertanyaan, bukan komentar. Terima kasih.
Quassnoi
1
Ini jawaban yang benar asalkan susunan asli Anda bersifat umum, bukan bin.
greenoldman
261

Saya selalu memecahkan ini dengan menggunakan yang lebih rendah:

SELECT * FROM trees WHERE LOWER( trees.title ) LIKE  '%elm%'
cwallenpoole
sumber
47
and spoil index use
Your Common Sense
3
Apakah MySQL 5 memiliki operator ILIKE?
Luke Maurer
27
meskipun untuk pencarian %% toh itu tidak masalah :)
Your Common Sense
5
@Col. - Harus diakui, ini kurang dari ideal untuk kolom yang diindeks, tetapi akan berfungsi untuk struktur yang sudah ada. Saya juga menemukan bahwa pencarian case-insensitive lebih sering pada kolom yang tidak diindeks pula.
cwallenpoole
1
Kolasi default sudah CI. Jadi, masalah sebenarnya bukan pada pertanyaan khusus ini. Tapi jawaban SO-style masih sempurna.
Akal Sehat Anda
48

Sensitivitas huruf didefinisikan dalam pengaturan kolom / tabel / pengaturan basis data. Anda dapat melakukan kueri di bawah susunan khusus dengan cara berikut:

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

misalnya.

(Ganti utf8_general_cidengan pemeriksaan apa pun yang menurut Anda berguna). The _cisingkatan kasus sensitif .

aioobe
sumber
1
Di MySQL 5.6 saya mendapatkan ERROR 1273 (HY000): Collation tidak dikenal: 'utf_general_ci' . Saya kira susunan ini telah dihapus dari MySQL? utf8_general_ciberfungsi dengan baik, meskipun.
Mark Amery
1
Punya masalah yang sama. Anda harus memperbaiki COLLATEatau melakukan trik sederhana seperti ini ( LOWER()kedua string Anda sebelum perbandingan)
Menelaos Kotsollaris
Di MySQL 5.6+ atau MariaDB 10+ Anda hanya perlu menyediakan instruksi COLLATE sebelum kondisi Anda. Jadi ini berhasil:SELECT * FROM products WHERE name COLLATE utf8_general_ci LIKE 'AB47TU';
stamster
41

Ini adalah contoh dari query LIKE:

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

Sekarang, case-insensitive menggunakan RENDAH () func:

SELECT * FROM <table> WHERE LOWER(<key>) LIKE LOWER('%<searchpattern>%')
Federico Piragua
sumber
3
Sebenarnya ini adalah solusi yang cukup bagus terutama ketika Anda dihadapkan dengan COLLATEmasalah format
Menelaos Kotsollaris
27

Cukup gunakan:

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

Atau Gunakan

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

Keduanya berfungsi sama

Vi8L
sumber
15

Saya melakukan sesuatu seperti itu.

Mendapatkan nilai dalam huruf kecil dan MySQL melakukan sisanya

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

Dan Untuk MySQL PDO Alternatif:

        $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();
Dave Doga Oz
sumber
6

Saya pikir permintaan ini akan melakukan pencarian case-sensitive:

SELECT * FROM trees WHERE trees.`title` ILIKE '%elm%';
cgupta
sumber
1
Saya mendapatkan kesalahan sintaks pada mysql 5.5 saat menggunakan ILIKE dalam pertanyaan saya
Steel Brain
18
Ini hanya berfungsi untuk PostgreSQL; bukan MySQL. postgresql.org/docs/current/static/functions-matching.html
Martin Tournoij
Seperti yang sudah disebutkan, pertanyaannya adalah tentang MySQL dan jawabannya adalah tentang PostgreSQL dan tentu saja tidak bekerja dengan MySQL. Saya tidak memilihnya tetapi tidak bisa bertanya-tanya dari mana suara itu berasal ...
silverdr
5

menggunakan ILIKE

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

itu berhasil untuk saya !!

Zarzis ABS
sumber
9
MySQL tidak mendukung ILIKE.
ttarchala
3
Itu berfungsi untuk PostgreSQL, pertanyaannya adalah mengenai MySQL.
Telmo Trooper
4

Anda tidak perlu ke ALTERmeja apa pun. Cukup gunakan kueri berikut, sebelum SELECTkueri aktual yang ingin Anda gunakan wildcard:

    set names `utf8`;
    SET COLLATION_CONNECTION=utf8_general_ci;
    SET CHARACTER_SET_CLIENT=utf8;
    SET CHARACTER_SET_RESULTS=utf8;
Lopofsky
sumber
2
Ini adalah komentar yang sangat diremehkan. Ini menjawab pertanyaan paling umum. Saya pikir sintaks tabel alter juga penting, karena pertanyaannya mungkin ingin perbandingan hanya terbatas pada satu kolom.
Brian Chrisman
1

baik di mysql 5.5, seperti operator tidak sensitif ... jadi jika lembah Anda adalah elm atau ELM atau Elm atau eLM atau yang lainnya, dan Anda menggunakan seperti '% elm%', itu akan mencantumkan semua nilai yang cocok.

Saya tidak bisa mengatakan tentang versi mysql sebelumnya.

Jika Anda menggunakan Oracle, suka bekerja sebagai case-sensitive, jadi jika Anda mengetik seperti '% elm%', itu hanya berlaku untuk ini dan abaikan huruf besar ..

Aneh, tapi begini :)

pengguna21546
sumber
Ini tidak sepenuhnya benar. Ia bekerja seperti itu hanya jika susunan diatur ke *_ci, yang merupakan singkatan dari "case-sensitive". Karena ini adalah default untuk semua set karakter yang didukung (masalah show character set;untuk memeriksa ini) - jawabannya sebagian benar :-) Hanya alasannya yang salah. Ini bukan operator yang case-sensitive, ini adalah collation default.
silverdr
ya saya setuju dengan anda. Itu tergantung pada karakter dan masih jika Anda dalam produksi dengan karakter * _ci maka satu-satunya pilihan adalah menggunakan biner sebelum di mana klausa
user21546
1
SELECT name 
       FROM gallery 
       WHERE CONVERT(name USING utf8) LIKE _utf8 '%$q%' 
       GROUP BY name COLLATE utf8_general_ci LIMIT 5 
pengguna4189641
sumber
galeri adalah nama-tabel, nama adalah kolom pada tabel,
user4189641
2
tolong tambahkan beberapa penjelasan kode Anda yang menunjukkan apa yang dilakukannya dan bagaimana itu membantu - ini akan membantu orang lain di masa depan
Our Man in Panan
0

Anda harus mengatur penyandian dan pengumpulan yang tepat untuk tabel Anda.

Pengkodean tabel harus mencerminkan pengodean data aktual. Apa pengkodean data Anda?

Untuk melihat penyandian tabel, Anda bisa menjalankan kueri SHOW CREATE TABLE tablename

Akal Sehat Anda
sumber
0

Ketika saya ingin mengembangkan pencarian kasus yang tidak sensitif, saya selalu mengonversi setiap string menjadi huruf kecil sebelum melakukan perbandingan

Rbacarin
sumber
0

Anda dapat menggunakan metode berikut

 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;
    }

gunakan metode ini seperti di bawah ini

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