Jak wyszukiwać (bez rozróżniania wielkości liter) w kolumnie za pomocą symboli LIKE?

289

Rozejrzałem się dookoła i nie znalazłem, o co mi chodzi, więc proszę.

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

Działa to dobrze, ale nie, jeśli drzewo nosi nazwę Elm lub ELM itp.

Jak sprawić, by SQL nie rozróżniał wielkości liter w tym wyszukiwaniu symboli wieloznacznych?

Używam MySQL 5 i Apache.

David Morrow
źródło
3
Jeśli natknąłeś się na tę stronę, ale twoje ustawienia MySql działają na tym zapytaniu dla Elm lub ELM i CHCESZ rozróżniać małe i wielkie litery, zobacz BINARYtakie jak tutaj: stackoverflow.com/questions/7857669/…
joshuahedlund
Czy to nie zależy od sortowania pól / tabel? jak „ut8_general_CI”
Yousha Aleayoub
Jak go użyć do sekwencjonowania zapytania o węzeł?
Ashh,
MySQL likepowinien domyślnie nie uwzględniać wielkości liter.
Marko Bonaci

Odpowiedzi:

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

W rzeczywistości, jeśli dodasz COLLATE UTF8_GENERAL_CIdo definicji kolumny, możesz po prostu pominąć wszystkie te sztuczki: zadziała to automatycznie.

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

Spowoduje to również przebudowanie wszystkich indeksów w tej kolumnie, dzięki czemu będą mogły być używane do zapytań bez wiodącego „%”

Quassnoi
źródło
34
W rzeczywistości, jeśli dodasz COLLATE UTF8_GENERAL_CIdo definicji kolumny, możesz po prostu pominąć wszystkie te sztuczki: zadziała to automatycznie. ALTER TABLE trees MODIFY COLUMN title VARCHAR(…) CHARACTER SET UTF8 COLLATE UTF8_GENERAL_CI. Spowoduje to również przebudowanie wszystkich indeksów w tej kolumnie, dzięki czemu będą mogły być używane do zapytań bez wiodącego „%”.
Quassnoi
1
ALTER TABLE drzewa MODYFIKUJ KOLUMNĘ tytuł VARCHAR (…) wydaje się to najlepszy sposób, dzięki wielkie ... niech sql wykona pracę
David Morrow
10
Przyjazne przypomnienie, że jest to odpowiedź mysql. Jeśli używasz PostgreSQL, ILike jest rozwiązaniem na powyższe pytanie.
Steve
2
@RajanRawal: zamieść swoje pytanie jako pytanie, a nie komentarz. Dzięki.
Quassnoi,
1
To poprawna odpowiedź, o ile oryginalny zestaw był ogólny, a nie bin.
greenoldman
261

Zawsze rozwiązałem to, używając niższej:

SELECT * FROM trees WHERE LOWER( trees.title ) LIKE  '%elm%'
cwallenpoole
źródło
47
i wykorzystanie indeksu zepsucia
Your Common Sense
3
Czy MySQL 5 ma operatora ILIKE?
Luke Maurer
27
choć dla wyszukiwania %% to i tak nie ma znaczenia :)
Twój zdrowy rozsądek
5
@Przełęcz. - Wprawdzie nie jest to idealne rozwiązanie dla indeksowanych kolumn, ale będzie działać w przypadku struktury, która już istnieje. Odkryłem również, że wyszukiwania bez rozróżniania wielkości liter częściej występują w kolumnach, które i tak nie są indeksowane.
cwallenpoole,
1
Domyślnym zestawieniem jest już CI. Prawdziwy problem nie dotyczy tego konkretnego pytania. Ale wciąż jest to idealna odpowiedź w stylu SO.
Twój zdrowy rozsądek
48

Rozróżnianie wielkości liter jest określone w ustawieniach sortowania kolumn / tabel / bazy danych. Możesz wykonać zapytanie w ramach określonego sortowania w następujący sposób:

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

na przykład.

(Zamień na utf8_general_cidowolne zestawienie, które uznasz za przydatne). _ciOznacza wielkość liter ma znaczenie .

aioobe
źródło
1
W MySQL 5.6 otrzymuję ERROR 1273 (HY000): Nieznane sortowanie: 'utf_general_ci' . Zgaduję, że to sortowanie zostało usunięte z MySQL? utf8_general_cijednak działa dobrze.
Mark Amery
1
Miałem ten sam problem. Musisz albo naprawić swój, COLLATEalbo wykonać prostą sztuczkę, taką jak ta ( LOWER()obie struny przed porównaniem)
Menelaos Kotsollaris,
W MySQL 5.6+ lub MariaDB 10+ wystarczy dostarczyć instrukcję COLLATE przed spełnieniem warunku. Więc to działa:SELECT * FROM products WHERE name COLLATE utf8_general_ci LIKE 'AB47TU';
stamster
41

Oto przykład prostej kwerendy LIKE:

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

Teraz rozróżniana jest wielkość liter przy użyciu funkcji LOWER ():

SELECT * FROM <table> WHERE LOWER(<key>) LIKE LOWER('%<searchpattern>%')
Federico Piragua
źródło
3
W rzeczywistości jest to całkiem fajne rozwiązanie, zwłaszcza gdy masz do czynienia z COLLATEproblemami z formatem
Menelaos Kotsollaris,
27

Po prostu użyj:

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

Albo użyj

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

Obie funkcje działają tak samo

Vi8L
źródło
15

Robię coś takiego.

Pobieranie wartości małymi literami i MySQL zajmuje się resztą

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

I dla 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();
Dave Doga Oz
źródło
6

Myślę, że to zapytanie spowoduje wyszukiwanie bez rozróżniania wielkości liter:

SELECT * FROM trees WHERE trees.`title` ILIKE '%elm%';
cgupta
źródło
1
Dostaję błąd składniowy na mysql 5.5 podczas korzystania z ILIKE w moich zapytaniach
Steel Brain
18
Działa to tylko w przypadku PostgreSQL; nie MySQL. postgresql.org/docs/current/static/functions-matching.html
Martin Tournoij
Jak już wspomniano, pytanie dotyczyło MySQL, a odpowiedź dotyczy PostgreSQL i na pewno nie działa z MySQL. Nie głosuję w dół, ale nie mogę się zastanawiać, skąd pochodzą głosy w górę ...
silverdr 24.01.2018
5

posługiwać się ILIKE

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

zadziałało dla mnie !!

ABS zarzis
źródło
9
MySQL nie obsługuje ILIKE.
ttarchala,
3
To działa dla PostgreSQL, pytanie dotyczyło MySQL.
Telmo Trooper
4

Nie potrzebujesz ALTERżadnego stołu. Po prostu skorzystaj z następujących zapytań, przed faktycznym SELECTzapytaniem, którego chcesz użyć z użyciem symbolu wieloznacznego:

    set names `utf8`;
    SET COLLATION_CONNECTION=utf8_general_ci;
    SET CHARACTER_SET_CLIENT=utf8;
    SET CHARACTER_SET_RESULTS=utf8;
Łopofski
źródło
2
To bardzo niedoceniany komentarz. Najogólniej odnosi się do pytania. Myślę, że składnia tabeli zmian jest również ważna, ponieważ pytanie może chcieć ograniczyć porównanie tylko do jednej kolumny.
Brian Chrisman,
1

dobrze w mysql 5.5, podobnie jak operator jest niewrażliwy ... więc jeśli twoją doliną jest wiąz, ELM lub Wiąz lub eLM lub jakikolwiek inny i użyjesz np. '% elm%', wyświetli wszystkie pasujące wartości.

Nie mogę powiedzieć o wcześniejszych wersjach mysql.

Jeśli korzystasz z Oracle, na przykład pracuj z rozróżnianiem wielkości liter, więc jeśli wpiszesz „% elm%”, przejdzie tylko do tego i zignoruje wielkie litery.

Dziwne, ale tak to jest :)

użytkownik21546
źródło
To nie do końca prawda. Działa w ten sposób tylko wtedy, gdy ustawione jest sortowanie *_ci, co oznacza „bez uwzględniania wielkości liter”. Ponieważ zdarza się, że jest to domyślne dla wszystkich obsługiwanych zestawów znaków (problem show character set;to sprawdzić) - odpowiedź jest częściowo zgodna z prawdą :-) Tylko przyczyna jest nieprawidłowa. To nie operator rozróżnia małe i wielkie litery, to domyślne sortowanie.
silverdr
tak, zgadzam się z tobą. Zależy to od postaci, a jeśli nadal jesteś w produkcji ze znakiem * _ci, wówczas jedyną opcją jest użycie
pliku
1
SELECT name 
       FROM gallery 
       WHERE CONVERT(name USING utf8) LIKE _utf8 '%$q%' 
       GROUP BY name COLLATE utf8_general_ci LIMIT 5 
użytkownik4189641
źródło
galeria to nazwa tabeli, nazwa to kolumna w tabeli,
user4189641
2
dodaj wyjaśnienie kodu pokazujące, co robi i jak pomaga - pomoże to innym w przyszłości
Our Man in Bananas
0

Musisz skonfigurować odpowiednie kodowanie i zestawianie tabel.

Kodowanie w tabeli musi odzwierciedlać faktyczne kodowanie danych. Jakie jest twoje kodowanie danych?

Aby zobaczyć kodowanie tabeli, możesz uruchomić zapytanie SHOW CREATE TABLE tablename

Twój zdrowy rozsądek
źródło
0

Kiedy chcę opracować niewrażliwe wyszukiwanie wielkości liter, zawsze dokonuję porównania każdego łańcucha na małe litery

Rbacarin
źródło
0

Możesz użyć następującej metody

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

użyj tej metody jak poniżej

   $where =  $this->generateStringCondition($yourSearchString,  'LOWER(columnName)','or', 'like',  '%', '%');
  $sql = "select * from table $where";
król neo
źródło