sql >> Databasteknik >  >> RDS >> Mysql

Hur använder man regexp på resultaten av en underfråga?

Prova någon av dessa frågor:

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

eller

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

Om antalet "slutsiffror" inte är fast, kan du också använda:

LIKE concat(u.phone_no, '%')

eller

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

Men i det här fallet kan du behöva använda SELECT DISTICT a.phone_no om det är möjligt att en users.phone_no är en följd av en annan users.phone_no (t.ex. 99123 och 991234).

Uppdatera

Efter att ha kört några tester med 10 000 rader för användartabell och 100 000 rader för tillträdestabell kom jag till följande fråga:

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

fiol

På så sätt kan du använda REGEXP och har fortfarande bra prestanda. Den här frågan körs nästan omedelbart i mitt testfall.

Logiskt sett behöver du bara REGEXP-villkoren. Men på större tabeller kan frågan timeout. Att använda ett LIKE-villkor kommer att filtrera resultatuppsättningen före REGEXP-kontroll. Men även att använda LIKE fungerar inte frågan särskilt bra. Av någon anledning använder MySQL inte en intervallkontroll för anslutningen. Så jag lade till en explicit intervallkontroll:

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

Med denna kontroll kan du ta bort LIKE-villkoret från JOIN-delen.

UNION-delen är en ersättning för DISTICT. MySQL verkar översätta DISTINCT till en GROUP BY-sats, som inte fungerar bra. Genom att använda UNION med en tom resultatuppsättning tvingar jag MySQL att ta bort dubbletter efter SELECT. Du kan ta bort den raden om du använder ett fast antal efterföljande siffror.

Du kan justera REGEXP-mönstren efter dina behov:

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

Om du bara behöver REGEXP för att kontrollera längden på phone_no kan du också använda ett LIKE-villkor med platshållaren '_'.

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

eller kombinera ett LIKE-villkor med en STR_LENGTH-kontroll.



  1. Hur man hittar namnet på en begränsning i Oracle

  2. Få alla användare utom nuvarande inloggade användare i laravel vältalig

  3. Söker råd om en relaterad videofråga på ett taggat videosystem

  4. sql facklig ordning