2009-09-06 14 views
36

Ho 2 tabelle, dico tabella A e tabella B e voglio eseguire un join, ma la condizione di corrispondenza deve essere dove una colonna da A 'è come' una colonna da B che significa che tutto può venire prima o dopo il colonna in B:come usare un like con un join in sql?

ad esempio: se la colonna in A è 'pippo'. Quindi il join corrisponderebbe se la colonna in B è o: "fooblah", "somethingfooblah" o semplicemente "foo". So come usare i caratteri jolly in una dichiarazione standard simile, ma sono confuso quando faccio un join. Ha senso ciò? Grazie.

risposta

16

In MySQL si potrebbe provare:

SELECT * FROM A INNER JOIN B ON B.MYCOL LIKE CONCAT('%', A.MYCOL, '%');

Naturalmente questo sarebbe una query massicciamente inefficiente perché sarebbe fare una scansione completa della tabella.

Aggiornamento: Ecco una prova


create table A (MYCOL varchar(255)); 
create table B (MYCOL varchar(255)); 
insert into A (MYCOL) values ('foo'), ('bar'), ('baz'); 
insert into B (MYCOL) values ('fooblah'), ('somethingfooblah'), ('foo'); 
insert into B (MYCOL) values ('barblah'), ('somethingbarblah'), ('bar'); 
SELECT * FROM A INNER JOIN B ON B.MYCOL LIKE CONCAT('%', A.MYCOL, '%'); 
+-------+------------------+ 
| MYCOL | MYCOL   | 
+-------+------------------+ 
| foo | fooblah   | 
| foo | somethingfooblah | 
| foo | foo    | 
| bar | barblah   | 
| bar | somethingbarblah | 
| bar | bar    | 
+-------+------------------+ 
6 rows in set (0.38 sec) 
+1

Grazie .. come potrei ottenere la stessa funzionalità ma renderla più efficiente? –

+0

Ecco come lo faresti. Se è necessario che sia più efficiente, è possibile indicizzare il campo MYCOL nella tabella B. –

+0

Se si utilizza il tipo di tabella MyISAM, è possibile provare un indice di testo completo e vedere se questo aiuta. Generalmente però, la ricerca a testo integrale non è un punto di forza di MySQL. Se la ricerca full text è una parte fondamentale della tua applicazione, considera qualcosa come Apache Lucene - http://lucene.apache.org/java/docs/ – Asaph

63

Utilizzando INSTR:

SELECT * 
    FROM TABLE a 
    JOIN TABLE b ON INSTR(b.column, a.column) > 0 

Utilizzando LIKE:

SELECT * 
    FROM TABLE a 
    JOIN TABLE b ON b.column LIKE '%'+ a.column +'%' 

Utilizzando LIKE, con CONCAT:

SELECT * 
    FROM TABLE a 
    JOIN TABLE b ON b.column LIKE CONCAT('%', a.column ,'%') 

presente che in tutte le opzioni, probabilmente si vorrà guidare i valori della colonna in maiuscolo prima di confrontare per garantire che si stanno ottenendo partite senza preoccupazioni per la sensibilità caso:

SELECT * 
    FROM (SELECT UPPER(a.column) 'ua' 
     TABLE a) a 
    JOIN (SELECT UPPER(b.column) 'ub' 
     TABLE b) b ON INSTR(b.ub, a.ua) > 0 

Il più efficace dipenderà in ultima analisi dalla Uscita EXPLAIN plan.

JOIN clausole sono identiche a scrivere clausole WHERE. La sintassi JOIN viene anche denominata ANSI JOIN perché erano standardizzati. Non-ANSI JOIN assomigliare:

SELECT * 
    FROM TABLE a, 
     TABLE b 
WHERE INSTR(b.column, a.column) > 0 

io non ho intenzione di perdere tempo con un esempio non ANSI LEFT JOIN. Il vantaggio della sintassi ANSI JOIN è che separa ciò che unisce le tabelle da ciò che sta effettivamente accadendo nella clausola WHERE.

+0

Qual è la migliore velocità tra LIKE e INSTR per (nome di dominio per esempio)? – Meloman

5

Se questo è qualcosa che devi fare spesso ... allora si consiglia di denormalizzare la relazione tra le tabelle A e B.

Per esempio, su Inserisci per tabella B, si potrebbe scrivere zero o più voci a una tabella di giunzioni che associa B a A in base alla mappatura parziale. Allo stesso modo, le modifiche a entrambe le tabelle potrebbero aggiornare questa associazione.

Questo dipende dalla frequenza con cui le tabelle A e B vengono modificate. Se sono abbastanza statici, prendere un colpo su INSERT è meno doloroso di colpi ripetuti su SELECT.

+2

Questa è una buona soluzione, ma non è esatto chiamarla denormalizzazione. –

+2

Abbastanza giusto. Chiamalo quindi un tavolo di congiunzione –

1

L'utilizzo di criteri condizionali in un join è decisamente diverso dalla clausola Where. La cardinalità tra le tabelle può creare differenze tra le clausole Join e Where.

Ad esempio, l'utilizzo di una condizione simile in un outer join manterrà tutti i record nella prima tabella elencata nel join.L'utilizzo della stessa condizione nella clausola Where modificherà implicitamente il join in un join interno. Il record deve essere generalmente presente in entrambe le tabelle per eseguire il confronto condizionale nella clausola Where.

Generalmente uso lo stile indicato in una delle risposte precedenti.

tbl_A as ta 
    LEFT OUTER JOIN tbl_B AS tb 
      ON ta.[Desc] LIKE '%' + tb.[Desc] + '%' 

In questo modo posso controllare il tipo di join.