Regex e pattern matching per la data quality
La data quality parte spesso dalla validazione dei formati: email, partite IVA, codici fiscali, numeri di telefono. Storicamente in T-SQL si usavano LIKE (con i wildcard %, _, [ ], [^ ]) e PATINDEX, che coprono pattern semplici ma non gestiscono quantificatori, alternanze o gruppi di cattura. Le nuove funzioni regex — REGEXP_LIKE, REGEXP_REPLACE, REGEXP_SUBSTR, REGEXP_INSTR, REGEXP_COUNT — colmano il gap sul motore SQL più recente e in Azure SQL.
Il criterio di scelta è per intento:
REGEXP_LIKEè un predicato (vero/falso): ideale in unaCHECK constraintper bloccare all’origine i dati non conformi, o inWHEREper isolare le righe sporche.REGEXP_REPLACEnormalizza e pulisce (rimuove spazi, uniforma separatori).REGEXP_SUBSTR/REGEXP_INSTRestraggono o localizzano una porzione.REGEXP_COUNTconta le occorrenze.
Trade-off chiave: le funzioni regex in WHERE sono tipicamente non-SARGable, quindi non sfruttano gli indici e forzano uno scan. Su grandi volumi conviene restringere prima il set con un predicato SARGable (es. LIKE 'prefisso%', senza wildcard iniziale) e applicare la regex solo sul residuo, oppure materializzare un flag di validità con una computed column persistita.
Fuzzy matching ed edit distance
Il fuzzy matching serve quando i valori dovrebbero coincidere ma differiscono per errori di battitura, abbreviazioni o varianti fonetiche — tipico nella deduplica delle anagrafiche. Due famiglie distinte:
- Fonetico:
SOUNDEXgenera un codice basato sul suono,DIFFERENCEconfronta dueSOUNDEXrestituendo un valore 0–4. Riconosce “Smith” ≈ “Smyth”, ma è tarato sull’inglese e ignora le trasposizioni. - Edit distance (Levenshtein): conta inserimenti, cancellazioni e sostituzioni necessarie a trasformare una stringa nell’altra. Cattura i typo (“Rossi” vs “Rosi”) meglio del fonetico. Attenzione: la distanza di Levenshtein non è una funzione nativa di T-SQL; va implementata con una UDF (scalare o CLR) oppure gestita a monte.
Per il matching massivo e la deduplica strutturata, SSIS offre le trasformazioni Fuzzy Lookup e Fuzzy Grouping (con soglia di similarità), mentre Data Quality Services fornisce knowledge base e matching policy. Sul piano del significato — non della stringa — la ricerca si appoggia oggi agli embeddings e al vector type con la vector search: utile per trovare record concettualmente simili, complementare e non sostitutivo del fuzzy testuale.
Full-text search per la ricerca testuale
Quando la ricerca è su testo lungo (descrizioni, documenti, note) e per parole o frasi, LIKE '%parola%' è lento e non-SARGable. La full-text search costruisce un full-text index su un full-text catalog e offre due predicati:
CONTAINS/CONTAINSTABLE: preciso, supporta operatori booleani, ricerca di prefisso, prossimità (NEAR), forme flesse (inflectional) e thesaurus.FREETEXT/FREETEXTTABLE: linguaggio naturale, più permissivo, cerca per senso delle parole.
Le varianti *TABLE restituiscono un RANK di rilevanza, utile per ordinare i risultati. Per la data quality, la full-text search aiuta a individuare e classificare valori testuali non normalizzati; per la similarità concettuale, di nuovo, gli embeddings con la vector search coprono ciò che le sole parole chiave non catturano.
Trappole tipiche d’esame
- Validare il formato all’inserimento → soluzione: usa
REGEXP_LIKEin unaCHECK constraint, non un trigger complesso né la sola validazione applicativa; la constraint garantisce l’integrità a livello di dato. - Query regex lenta su tabella grande → soluzione: ricorda che le funzioni regex non sono SARGable; pre-filtra con un predicato indicizzabile o una computed column persistita, non aggiungere un indice sperando che acceleri la regex.
- “Trova nomi che suonano uguali” → soluzione:
SOUNDEX/DIFFERENCE(fonetico); per i typo carattere-per-carattere serve invece l’edit distance. - Levenshtein “nativo” in T-SQL → soluzione: trappola classica: non esiste una funzione built-in; va scritta come UDF/CLR o gestita con SSIS Fuzzy Lookup.
- Ricerca di frase o prossimità su testo lungo → soluzione:
CONTAINSconNEAR, nonLIKE '%...%'; per ordinare per rilevanza usaCONTAINSTABLE/FREETEXTTABLEcon ilRANK. - “Trova record simili per significato” → soluzione: è similarità semantica → embeddings e vector search, non full-text né fuzzy testuale, che lavorano su parole e caratteri.