2016-05-02 32 views
16

Mam tabelę MySQL (test) z kodowaniem znaków UTF-8. Istnieją trzy wpisy, dwa wpisy z normalnymi znakami i inną nazwą ze znakami akcentującymi.Jak odfiltrować kolumnę za pomocą znaków nieakcentowanych za pomocą zapytania wyboru

CREATE TABLE test (
    id Integer, 
    name VARCHAR(50), 
    PRIMARY KEY (id) 
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; 

INSERT INTO `test` (`id`, `name`) VALUES (1, 'aaaa'); 
INSERT INTO `test` (`id`, `name`) VALUES (2, 'AAAA'); 
INSERT INTO `test` (`id`, `name`) VALUES (3, 'áááá'); 

Jeśli uruchomić następującą kwerendę wybierającą, to zwraca wszystkie 3 prace

wynik rzeczywisty: -

select * from test where name like '%aa%'; 

id | name 
----|---- 
1 | aaaa 
2 | AAAA 
3 | áááá 

Zamiast tego, należy wrócić ostatni wpis z identyfikatorem = 3.

Nie chcę używać "BINARNE" LUB "KOLLATE utf8_bin", ponieważ zwraca tylko rozróżnianie wielkości liter.

muszę szukanie normalne sznurkiem jak zapytania, na przykład: -

Oczekiwany rezultat: -

select * from test where name like '%aa%'; 

id | name 
---|----- 
1 | aaaa 
2 | AAAA 
+0

Po prostu. Możesz usunąć akcenty z kolumny przed wyszukiwaniem (wpisz swoją funkcję), np. 'where removeaccent (name) LIKE '% aa%'' –

+0

Getting "ERROR 1305 (42000): FUNCTION DB.removeaccent nie istnieje" gdzie mam napisać funkcję? – SST

+0

Wszelkie wejścia tutaj naprawdę docenione – SST

Odpowiedz

6

utf8_bin sortowania jest to, czego potrzeba do wymogu, aby obsłużyć akcenty

Nie chcę używać 'BINARNE' LUB 'KOLLANU utf8_bin', ponieważ zwraca tylko rozróżnianie wielkości liter.

Jest to łatwiejsze (i bardziej wydajnych) do rozwiązania z utf8_bin niż rozwiązanie problemu akcent z inną zestawień

SELECT * FROM test WHERE LOWER(name) like '%aa%' COLLATE utf8_bin 

-> dodaje się po komentarzach

Zapytanie powyżej zakłada, że ​​parametry zapytania są nieznaczne, ale jeśli nie można modyfikować params, aby zawsze były minuscules, można również użyć tej wersji

SELECT * FROM test WHERE LOWER(name) like LOWER('%ÚÙ%') COLLATE utf8_bin 
+0

Dzięki za odpowiedź. Działa dobrze, gdy wyszukuję zwykły ciąg znaków. Jeśli wyszukuję "% ÚÙ%", to zwraca puste. dlaczego jego niepowodzenie? (| 4 | ÛÚÙëý | | 5 | uuëý |) – SST

+0

Przykro mi, ale nie określiłem, ponieważ zależy ci na wielkości liter, używamy LOWER, aby zamieniać małe litery na nazwę, ale wyszukiwane hasło musi być pisane małymi literami. – user3802077

+0

Czy istnieje możliwość przeszukiwania takich ciągów przy użyciu niewrażliwości na wielkość liter? – SST

4

utf8_bin jest zestawianie chcesz rozróżniać znaki akcentowane.

W zapytaniu użytkownik może lower uczynić wielkość liter nieodczuwalną.

CREATE TABLE `token` (
    `id` int(11) NOT NULL DEFAULT '0', 
    `name` varchar(50) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 

mysql> select * from token where lower(name) like '%aa%'; 
+----+------+ 
| id | name | 
+----+------+ 
| 1 | aaaa | 
| 2 | AAAA | 
+----+------+ 
2 rows in set (0.00 sec) 
+0

Powinno być zwrócone tylko pierwsze dwa wpisy .. mysql> wybierz * z tokena gdzie nazwa jak "% aa%"; (1, aaaa), (2, AAAA) – SST

+0

Niestety, źle zrozumiałem twoje pytanie. Zaktualizowano odpowiedź. –

1

można rozwiązać problemu stosując następujące zapytanie

select * from token where (convert(name using ASCII)) like '%aa%' 

convert służy do konwersji między charakterem ustawia

+0

W tym zapytaniu, jeśli mam mieszaną nazwę, taką jak "ÛÚÙëý" i "uuuëý", powyższe zapytanie zwraca pusty zestaw [mysql> select * z testu, gdzie name = convert (nazwa z użyciem ASCII) i nazwa taka jak "% uu% "; Zestaw pusty (0,00 s)]. Powinno to zwrócić wiersz, którego nazwa jest "uuuëý" – SST

+0

@SST -answer zmodyfikowany. Sprawdź teraz –

+0

Dziękuję @ Fathan !! Kiedy wykonuję to zapytanie [wybierz * z testu where (convert (name using ASCII)), takie jak '% ÚÙ%';], Zgłasza błąd .. ERROR 1267 (HY000): Nielegalna kombinacja sortowania (ascii_general_ci, IMPLICIT) i (utf8_general_ci, COERCIBLE) dla operacji 'like' – SST

1

Korzystanie RLIKE (regexp) może rozwiązać problem (będzie zwrócić oczekiwany rezultat przy użyciu większej wydajności wersję podobne)

z MySQL Dokumentacja:
Wyrażenie regularne jest skutecznym sposobem określania wzorzec dla złożonego wyszukiwania.
....REGEXP nie rozróżnia wielkości liter, z wyjątkiem sytuacji, gdy używane są ciągi binarne.

prostu zastąpić

where name like '%aa%' 

z

where Name rlike 'aa'; 

zrobić uwzględnia wielkości liter wyszukiwania wyrażenia 'aa'.

ALE:
To może być jakiś sposób niebezpieczne podejście jak nieoczekiwane wyniki mogą być produkowane przez porównanie znaki wielobajtowe według dokumentacji MySQL.