Mysql
 sql >> база данни >  >> RDS >> Mysql

Как да използвам regexp за резултатите от подзаявка?

Опитайте една от тези заявки:

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]+$'

или

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]+$'

Ако броят на "завършващите цифри" не е фиксиран, можете също да използвате:

LIKE concat(u.phone_no, '%')

или

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

Но в този случай може да се наложи да използвате SELECT DISTICT a.phone_no ако е възможно users.phone_no е подпоследователност на друг users.phone_no (напр. 99123 и 991234).

Актуализиране

След като изпълних някои тестове с 10K реда за таблица с потребители и 100K реда за таблица за допускане, стигнах до следната заявка:

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

цигулка

По този начин можете да използвате REGEXP и все още имат страхотно представяне. Тази заявка се изпълнява почти мигновено в моя тестов случай.

Логично се нуждаете само от условията на REGEXP. Но на по-големи таблици заявката може да изтече. Използването на условие LIKE ще филтрира набора от резултати преди проверката на REGEXP. Но дори и използването на LIKE заявката не се представя много добре. По някаква причина MySQL не използва проверка на диапазона за присъединяването. Така че добавих изрична проверка на диапазона:

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

С тази проверка можете да премахнете условието LIKE от частта JOIN.

Частта UNION е заместител на DISTICT. MySQL изглежда превежда DISTINCT в оператор GROUP BY, който не работи добре. Използвайки UNION с празен набор от резултати, принуждавам MySQL да премахва дубликати след SELECT. Можете да премахнете този ред, ако използвате фиксиран брой последни цифри.

Можете да коригирате шаблоните REGEXP според вашите нужди:

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

Ако имате нужда само от REGEXP, за да проверите дължината на phone_no, можете също да използвате условие LIKE с '_' placeholder.

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

или комбинирайте условие LIKE с проверка 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. Кога да използвате кой модел на разделяне на mysql

  2. SQLSTATE[42000]:Синтактична грешка или нарушение на достъпа:1055 Израз №3 от списъка SELECT не е в клауза GROUP BY и съдържа неагрегирани

  3. Причина за неправилно конфигурирана MySQL:опасно използване на относителен път

  4. Как да повторите изявленията за печат, докато изпълнявате sql скрипт

  5. Сортиране по дата (най-нови)