PDA

View Full Version : [SQL] Cercare valori in tabella con chiave "simile"


amedeoviscido
07-03-2008, 13:01
Ciao, ho un problema che ho già risolto, ma vorrei da voi un consiglio.
Il problema è individuare le righe che hanno parte della chiave in comune. Supponiamo di avere la tabella PROVA(ID) con ID chiave primaria.
Ho bisogno di trovare le righe tali che ID della 1° riga sia inserito IN FONDO alla 2° riga. In pratica, facciamo un esempio:

PROVA
1234567890
12345
67890

Mi deve trovare 67890 unitamente al riferimento 1234567890.

Io ho risolto così (PostgreSQL):

SELECT B.id, A.id FROM prova A, prova B WHERE A.id<>B.id AND strpos(A.id,B.id)>0

Ovvero con strpos, controllo che l'ID di B faccia parte dell'ID di A.
Tutto ok direte voi: non proprio direi io.
Con 5000 righe ci impiega 1 minuto, non sarebbe un problema, se non per il fatto che per fare un report ne deve fare a centinaia di queste query!
Io prima facevo semplicemente:

SELECT A.id,B.id FROM prova A JOIN prova B ON A.id=B.id
E ci metteva 15 ms. Il problema è che adesso le chiavi sono fatte in modo tale che se una finisce come l'altra allora deve trovare la "primaria".

gugoXX
07-03-2008, 14:07
Io farei cosi':


SELECT A.ID,B.ID FROM prova A,prova B WHERE A.id<>B.id
AND length(A.ID)>=length(B.ID)
AND SUBSTR(A.ID,length(A.ID)-Length(B.ID),length(B.ID))=B.ID

Ovvero come prima, ma come filtro anche
ma solo per i record di A la cui ultima parte di A.ID, lunga quanto B.ID, sia esattamente uguale a B.ID

(la clausola sulle lunghezze sarebbe da leggersi come:
ma solo tra le righe che hanno la lunghezza di A.ID >= alla lunghezza di B.ID,
altrimenti potrebbero effetti indesiderati a seconda del implementazione della SUBSTR su Postgres, in presenza di un indice di partenza negativo)

forse addirittura si puo' fare cosi':

SELECT A.ID,B.ID FROM prova A,prova B WHERE A.id<>B.id
AND length(A.ID)>=length(B.ID)
AND SUBSTR(A.ID,length(A.ID)-Length(B.ID))=B.ID

Sperando che la Substring abbia il significato di "fino alla fine della stringa" quando non c'e' il terzo parametro

amedeoviscido
07-03-2008, 23:42
Grazie per la risposta, domani faccio delle prove in ufficio (cronometrate) e ti faccio sapere, sarai curioso!
In effetti controllare la posizione di una stringa all'interno di un'altra è meno efficiente che il confronto diretto di due stringhe, a rigor di logica dovrebbe essere più veloce, vedremo!