MySQL LIKE IN ()?

La mia query attuale assomiglia a questa:

SELECT * FROM fiberbox f WHERE f.fiberBox LIKE '%1740 %' OR f.fiberBox LIKE '%1938 %' OR f.fiberBox LIKE '%1940 %' 

Ho fatto un po ‘di guardarmi intorno e non ho trovato nulla di simile ad un LIKE IN () – immagino che funzioni in questo modo:

 SELECT * FROM fiberbox f WHERE f.fiberbox LIKE IN('%140 %', '%1938 %', '%1940 %') 

Qualche idea? Sto solo pensando al problema nel modo sbagliato – un comando oscuro che non ho mai visto.

MySQL 5.0.77-community-log

Un REGEXP potrebbe essere più efficiente, ma dovresti eseguirne il benchmark per essere sicuro, ad es

 SELECT * from fiberbox where field REGEXP '1740|1938|1940'; 

La risposta di Paul Dixon ha funzionato brillantemente per me. Per aggiungere a questo, ecco alcune cose che ho osservato per coloro che sono interessati all’utilizzo di REGEXP:

Per realizzare più filtri LIKE con i caratteri jolly:

  SELECT * FROM fiberbox WHERE field LIKE '%1740 %' OR field LIKE '%1938 %' OR field LIKE '%1940 %'; 

Usa l’alternativa REGEXP:

  SELECT * FROM fiberbox WHERE field REGEXP '1740 |1938 |1940 '; 

Valori tra virgolette REGEXP e tra i | (OR) gli operatori sono considerati come caratteri jolly. In genere, REGEXP richiede espressioni con caratteri jolly come (. *) 1740 (. *) Per funzionare come% 1740%.

Se hai bisogno di più controllo sul posizionamento del carattere jolly, utilizza alcune di queste varianti:

Per ottenere un risultato simile con il posizionamento jolly controllato:

 SELECT * FROM fiberbox WHERE field LIKE '1740 %' OR field LIKE '%1938 ' OR field LIKE '%1940 % test'; 

Uso:

 SELECT * FROM fiberbox WHERE field REGEXP '^1740 |1938 $|1940 (.*) test'; 
  • Posizionando ^ davanti al valore indica l’inizio della linea.

  • Inserendo $ dopo il valore indica fine riga.

  • Il posizionamento (. *) Si comporta in modo simile al carattere jolly%.

  • Il . indica un singolo carattere, ad eccezione delle interruzioni di riga. Collocazione inside () con * (. *) aggiunge uno schema ripetitivo che indica qualsiasi numero di caratteri fino alla fine della riga.

Esistono metodi più efficienti per limitare le corrispondenze specifiche, ma ciò richiede una revisione più approfondita delle espressioni regolari. NOTA: non tutti i pattern regex sembrano funzionare nelle istruzioni MySQL. Avrai bisogno di testare i tuoi modelli e vedere cosa funziona.

Infine, per realizzare più filtri LIKE e NOT LIKE:

 SELECT * FROM fiberbox WHERE field LIKE '%1740 %' OR field LIKE '%1938 %' OR field NOT LIKE '%1940 %' OR field NOT LIKE 'test %' OR field = '9999'; 

Usa l’alternativa REGEXP:

 SELECT * FROM fiberbox WHERE field REGEXP '1740 |1938 |^9999$' OR field NOT REGEXP '1940 |^test '; 

O alternativa mista:

 SELECT * FROM fiberbox WHERE field REGEXP '1740 |1938 ' OR field NOT REGEXP '1940 |^test ' OR field NOT LIKE 'test %' OR field = '9999'; 

Notate che ho separato il NON impostato in un filtro WHERE separato. Ho sperimentato l’utilizzo di schemi di negazione, modelli di previsione e così via. Tuttavia, queste espressioni non sembravano produrre i risultati desiderati. Nel primo esempio sopra, utilizzo ^ 9999 $ per indicare la corrispondenza esatta. Ciò consente di aggiungere corrispondenze specifiche con le corrispondenze con caratteri jolly nella stessa espressione. Tuttavia, puoi anche mescolare questi tipi di istruzioni come puoi vedere nel secondo esempio elencato.

Per quanto riguarda le prestazioni, ho eseguito alcuni test minori su un tavolo esistente e non ho riscontrato differenze tra le mie varianti. Tuttavia, immagino che le prestazioni potrebbero essere un problema con database più grandi, campi più grandi, conteggi record maggiori e filtri più complessi.

Come sempre, usa la logica sopra come ha senso.

Se vuoi saperne di più sulle espressioni regolari, ti consiglio http://www.regular-expressions.info come un buon sito di riferimento.

È ansible creare una vista in linea o una tabella temporanea, riempirla con valori e rilasciare questo:

 SELECT * FROM fiberbox f JOIN ( SELECT '%1740%' AS cond UNION ALL SELECT '%1938%' AS cond UNION ALL SELECT '%1940%' AS cond ) с ON f.fiberBox LIKE cond 

Questo, tuttavia, può restituire più righe per un fiberbox che è qualcosa come '1740, 1938' , quindi questa query può adattarsi meglio:

 SELECT * FROM fiberbox f WHERE EXISTS ( SELECT 1 FROM ( SELECT '%1740%' AS cond UNION ALL SELECT '%1938%' AS cond UNION ALL SELECT '%1940%' AS cond ) с WHERE f.fiberbox LIKE cond ) 

Regexp modo con elenco di valori

 SELECT * FROM table WHERE field regexp concat_ws("|", "111", "222", "333"); 

Siamo spiacenti, non esiste alcuna operazione simile a LIKE IN in mysql.

Se si desidera utilizzare l’operatore LIKE senza un join, è necessario farlo in questo modo:

 (field LIKE value OR field LIKE value OR field LIKE value) 

Sai, MySQL non ottimizzerà quella query, FYI.

Inverti gli operandi

 'a,b,c' like '%'||field||'%' 

Solo un piccolo consiglio:

Preferisco usare la variante RLIKE (esattamente lo stesso comando di REGEXP ) poiché suona più come linguaggio naturale ed è più breve; bene, solo 1 carattere.

Il prefisso “R” è per Reg. Exp., Ovviamente.

Presta solo nota a chiunque cerchi che REGEXP usi la funzionalità “LIKE IN”.

IN ti permette di fare:

 field IN ( 'val1', 'val2', 'val3' ) 

In REGEXP questo non funzionerà

 REGEXP ' val1$| val2$| val3$ ' 

Deve essere in una riga come questa:

 REGEXP 'val1$|val2$|val3$' 

Questo sarebbe corretto:

 SELECT * FROM table WHERE field regexp concat_ws("|",( "111", "222", "333" )); 

È ansible ottenere il risultato desiderato con l’aiuto di espressioni regolari .

 SELECT fiberbox from fiberbox where fiberbox REGEXP '[1740|1938|1940]'; 

Possiamo testare la query sopra, fare clic su SQL fiddle

 SELECT fiberbox from fiberbox where fiberbox REGEXP '[174019381940]'; 

Possiamo testare la query sopra, fare clic su SQL fiddle