Szukaj "dopasowanie całego słowa" w MySQL

Chciałbym napisać zapytanie SQL, które wyszukuje słowo kluczowe w polu tekstowym, ale tylko wtedy, gdy jest to " dopasowanie całego słowa "(np. gdy szukam "rid", nie powinno pasować do "arid", ale powinno pasować do "a rid".

Używam MySQL.

Na szczęście wydajność nie jest krytyczna w tej aplikacji, a rozmiar bazy danych i rozmiar napisów są wygodnie małe, ale wolałbym to zrobić w SQL niż w PHP.

Author: mike nelson, 2009-03-18

6 answers

Możesz użyć REGEXP oraz znaczniki [[:<:]] i [[:>:]] wyrazowo-graniczne:

SELECT *
FROM table 
WHERE keywords REGEXP '[[:<:]]rid[[:>:]]'

Update for 2020: (faktycznie 2018+)

MySQL zaktualizował swój RegExp-Engine w wersji 8.0.4, więc będziesz teraz musiał użyć " standard " word boundary marker \B:

SELECT *
FROM table 
WHERE keywords REGEXP '\\brid\\b'

Należy również pamiętać, że trzeba uniknąć ukośnika, umieszczając drugi ukośnik.

 155
Author: LukeH,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-01-10 11:40:25

Znaleziono odpowiedź zapobiegającą zderzeniu klasycznej granicy słowa [[::<::]] ze znakami specjalnymi np.@#$%^&*

Zastąp..

SELECT *
FROM table 
WHERE keywords REGEXP '[[:<:]]rid[[:>:]]'
Tym..
SELECT *
FROM table 
WHERE keywords REGEXP '([[:blank:][:punct:]]|^)rid([[:blank:][:punct:]]|$)'

Ten ostatni pasuje (spacja, tabulator itp.) | | (przecinek, nawias itp.) / / początek / koniec linii. Bardziej "skończone" dopasowanie granicy słowa.

 29
Author: Ricky Boyce,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-16 01:00:40

Możesz użyć like ze znacznikiem wildcard, aby złapać możliwości( na początku, na końcu, w środku i sam), coś takiego powinno wystarczyć:

Wybierz bla bla bla gdzie kolumna jak ' rid %' lub kolumny typu "% rid" lub kolumny typu " % rid %" or column = " rid "

 5
Author: paxdiablo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-05-01 22:04:47

Użyj wyrażenia regexp z granicami słów, ale jeśli chcesz również przeszukiwać bez akcentu, zwróć uwagę, że wyrażenie REGEXP jest operatorem jednobajtowym, więc nie warto mieć zestawiania utf8_general_ci, dopasowanie nie będzie niewrażliwe na akcent.

Aby mieć zarówno niewrażliwy akcent, jak i dopasowanie całego słowa, określ słowo napisane w taki sam sposób, w jaki zrobiła to (przestarzała) funkcja PHP sql_regcase ().

W rzeczywistości:

  • Utf8_general_ci pozwala na utworzenie równości (gdzie pole = wartość) wyszukiwanie niewrażliwe na wielkość liter i akcent, ale nie pozwala określić całego dopasowania wyrazów (znaczniki granic wyrazów nie są rozpoznawane)

  • Podobnie pozwala na przeszukiwanie bez rozróżniania liter i akcentów, ale musisz ręcznie określić wszystkie kombinacje możliwych znaków granic wyrazów (znaczniki granic wyrazów nie są rozpoznawane)

  • Granice wyrazów [[:<:>:]] są obsługiwane w funkcji REGEXP, która jest pojedynczym bajtem, więc nie wykonuje akcentu niewrażliwego Szukaj.

Rozwiązaniem jest użycie wyrażenia regularnego z granicami słów i słowa zmodyfikowanego w sposób, w jaki robi to sql_regcase.

Używane na http://www.nonsolodiete.it

 4
Author: Marco Marsala,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-07-09 16:07:47
select * from table where Locate('rid ', FieldToSearch) > 0 
      or Locate(' rid', FieldToSearch) > 0

To zajmie znalezienie rid tam, gdzie jest poprzedzone lub poprzedzone spacją, można rozszerzyć podejście, aby wziąć pod uwagę .,?! i tak dalej, nie eleganckie, ale łatwe.

 1
Author: MrTelly,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-18 04:26:29

To jest najlepsza odpowiedź jaką do tej pory wymyśliłem:

SELECT * FROM table 
WHERE keywords REGEXP '^rid[ $]' OR keywords REGEXP ' rid[ $]'

Uprościłbym to do:

SELECT *
FROM table
WHERE keywords REGEXP '[^ ]rid[ $]'

Ale [ ^ ] ma specjalne znaczenie "nie spacja", a nie "Linia-początek lub spacja".

Jak REGEXP porównuje się do wielu podobnych warunków? (Wydajność nie ma znaczenia w tej aplikacji.)

 1
Author: Oddthinking,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-18 04:35:01