Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Jak używać wyrażenia regularnego na wynikach podzapytania?

Wypróbuj jedno z tych zapytań:

SELECT a.phone_no
FROM admission a
JOIN users u on a.phone_no LIKE concat(u.phone_no, '__')
WHERE u.phone_no REGEXP  '^(99)+[0-9]+$'

lub

SELECT a.phone_no
FROM admission a
JOIN users u on a.phone_no REGEXP concat('^', u.phone_no, '[0-9]{2}$')
WHERE u.phone_no REGEXP  '^(99)+[0-9]+$'

Jeśli liczba „cyfr końcowych” nie jest ustalona, ​​możesz również użyć:

LIKE concat(u.phone_no, '%')

lub

REGEXP concat('^', u.phone_no, '[0-9]*$')

Ale w tym przypadku może być konieczne użycie SELECT DISTICT a.phone_no jeśli to możliwe, że users.phone_no jest podciągiem innego users.phone_no (np. 99123 i 991234).

Aktualizacja

Po przeprowadzeniu kilku testów z 10 tys. wierszami dla tabeli użytkowników i 100 tys. wierszami dla tabeli przyjęć, doszedłem do następującego zapytania:

SELECT a.phone_no
FROM admission a
JOIN users u 
    ON  a.phone_no >= u.phone_no
    AND a.phone_no < CONCAT(u.phone_no, 'z')
    AND a.phone_no LIKE CONCAT(u.phone_no, '%')
    AND a.phone_no REGEXP CONCAT('^', u.phone_no, '[0-9]*$')
WHERE   u.phone_no LIKE  '99%'
    AND u.phone_no REGEXP  '^(99)+[0-9]*$'
UNION SELECT 0 FROM (SELECT 0) dummy WHERE 0

skrzypce

W ten sposób możesz użyć REGEXP i nadal mają świetną wydajność. To zapytanie jest wykonywane prawie natychmiast w moim przypadku testowym.

Logicznie potrzebujesz tylko warunków REGEXP. Jednak w przypadku większych tabel może nastąpić przekroczenie limitu czasu zapytania. Użycie warunku LIKE spowoduje filtrowanie zestawu wyników przed sprawdzeniem REGEXP. Ale nawet przy użyciu LIKE zapytanie nie działa zbyt dobrze. Z jakiegoś powodu MySQL nie używa sprawdzania zakresu dla złączenia. Dodałem więc wyraźne sprawdzenie zakresu:

    ON  a.phone_no >= u.phone_no
    AND a.phone_no < CONCAT(u.phone_no, 'z')

Dzięki tej kontroli możesz usunąć warunek LIKE z części JOIN.

Część UNION zastępuje DISTICT. MySQL wydaje się tłumaczyć DISTINCT na instrukcję GROUP BY, która nie działa dobrze. Używając UNION z pustym zestawem wyników, zmuszam MySQL do usunięcia duplikatów po SELECT. Możesz usunąć tę linię, jeśli użyjesz stałej liczby końcowych cyfr.

Możesz dostosować wzorce REGEXP do swoich potrzeb:

...
    AND a.phone_no REGEXP CONCAT('^', u.phone_no, '[0-9]{2}$')
...
    AND u.phone_no REGEXP  '^(99)+[0-9]{8}$'
...

Jeśli potrzebujesz tylko REGEXP do sprawdzenia długości numeru telefonu, możesz również użyć warunku LIKE ze znakiem zastępczym „_”.

    AND a.phone_no LIKE CONCAT(u.phone_no, '__')
...
    AND u.phone_no LIKE '99________$'

lub połącz warunek LIKE z kontrolą STR_LENGTH.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Użyj LIKE %..% z wartościami pól w MySQL

  2. Alternatywne sposoby na uniknięcie limitu geokodów w Mapach Google

  3. Pisanie podzapytania przy użyciu Zend DB

  4. Jak uzyskać zestaw wyników, taki jak funkcja opóźnienia Oracle?

  5. Skanowanie tabeli mysql od dołu