sql >> Database teknologi >  >> RDS >> Mysql

Hvordan bruger man regexp på resultaterne af en underforespørgsel?

Prøv en af ​​disse forespørgsler:

VÆLG a.phone_noFROM adgang aJOIN brugere u på a.phone_no LIKE concat(u.phone_no, '__')WHERE u.phone_no REGEXP '^(99)+[0-9]+$' 

eller

SELECT a.phone_noFROM adgang til JOIN brugere u på a.phone_no REGEXP concat('^', u.phone_no, '[0-9]{2}$')WHERE u.phone_no REGEXP '^(99 )+[0-9]+$' 

Hvis antallet af "søgende cifre" ikke er fast, kan du også bruge:

LIKE concat(u.phone_no, '%') 

eller

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

Men i dette tilfælde skal du muligvis bruge SELECT DISTICT a.phone_no hvis det er muligt, at en users.phone_no er en efterfølger af en anden users.phone_no (f.eks. 99123 og 991234).

Opdater

Efter at have kørt nogle tests med 10.000 rækker til brugertabel og 100.000 rækker til adgangstabeller kom jeg til følgende forespørgsel:

SELECT a.phone_noFROM adgang aJOIN brugere u ON a.phone_no>=u.phone_no AND a.phone_no  

violin

På denne måde kan du bruge REGEXP og stadig have en fantastisk præstation. Denne forespørgsel udføres næsten øjeblikkeligt i mit testcase.

Logisk set behøver du kun REGEXP-betingelserne. Men på større tabeller kan forespørgslen timeout. Brug af en LIKE-tilstand vil filtrere resultatsættet før REGEXP-tjek. Men selv ved at bruge LIKE fungerer forespørgslen ikke særlig godt. Af en eller anden grund bruger MySQL ikke en rækkeviddekontrol til joinforbindelsen. Så jeg tilføjede en eksplicit rækkeviddekontrol:

 PÅ a.phone_no>=u.phone_no OG a.phone_no  

Med dette tjek kan du fjerne LIKE-tilstanden fra JOIN-delen.

UNION delen er en erstatning for DISTICT. MySQL ser ud til at oversætte DISTINCT til en GROUP BY-sætning, som ikke fungerer godt. Ved at bruge UNION med et tomt resultatsæt tvinger jeg MySQL til at fjerne dubletter efter SELECT. Du kan fjerne den linje, hvis du bruger et fast antal efterfølgende cifre.

Du kan justere REGEXP-mønstrene til dine behov:

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

Hvis du kun har brug for REGEXP for at kontrollere længden af ​​phone_no, kan du også bruge en LIKE-tilstand med '_' pladsholderen.

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

eller kombiner en LIKE-tilstand med en STR_LENGTH-kontrol.



  1. Laravel:Hvordan gemmer jeg data i json-format i databasen?

  2. MYSQL:Hvor klausulen er tvetydig

  3. Brug af SQL til at finde det samlede antal kunder med over X ordrer

  4. Hvad er hurtigere:Mange rækker eller mange kolonner?