2014-10-29 14 views
6

Vorrei chiedere un consiglio se qualche funzione in SQL Server che mi consente di eseguire una corrispondenza parziale per un elenco di valori?TSQL - Corrispondenza parziale con LIKE per più valori

L'intera stringa che deve essere abbinata verrà inoltrata tramite la procedura di archiviazione.

Sto cercando di trovare altra alternativa prima di scrivere la mia funzione per dividere la stringa con una virgola e quindi unire tutti i risultati prima di restituire i dati al programma.

Ad esempio, vorrei passare la seguente stringa nel mio TSQL

mela, arancia, pera

nel mio WHERE clausola dovrebbe corrispondere

select * from store where fruits like 'apple%' 
select * from store where fruits like 'orange%' 
select * from store where fruits like 'pear%' 

Posso ottenere i risultati sopra riportati in una singola istruzione SQL anziché nella funzione di scrittura per interrompere ogni stringa?

dati nella mia tabella

apple red 
apple green 
orange sweet 
orange sour 
pear big 
pear small 

Così, quando ho passato nella stringa "mela, pera", ho bisogno di tornare

apple red 
apple green 
pear big 
pear small 
+2

Che cosa significa "frutti"? Non dire valori separati da virgola. Questo è un design molto, molto povero per un database relazionale. –

+0

Sto solo usando una semplice tabella per l'illustrazione. – user3015739

+0

Hai un problema fondamentale con la tua struttura dati. Non dovresti memorizzare elenchi di cose come stringhe. Invece, dovresti usare una tabella di giunzione. –

risposta

1

Prova questa, ma le prestazioni non essere grandioso

declare @parm varchar(200) 
set @parm = ','+'apple,orange,pear'+',' 

select * from store where charindex(fruit,@parm) > 0 
+0

Non ha funzionato perché non è possibile avere mela, arancione negli stessi dati. Sto solo usando la corrispondenza di modelli per trovare tutti i colori rosso mela, verde mela, arancione grande, arancione piccolo. – user3015739

+0

Mi spiace, digita - Ho invertito i parametri.Prova la versione modificata – Sparky

1

Potrebbe essere semplice come:

SELECT 
    * 
FROM 
    store 
WHERE 
    fruits LIKE 'apple%' 
    OR fruits LIKE 'orange%' 
    OR fruits LIKE 'pear%' 
+0

La stringa verrà passata da una procedura di archiviazione e devo restituire il set di dati utilizzando la corrispondenza del modello. Non ho problemi a scrivere una funzione per dividere la stringa e quindi unire i risultati. Prova solo ad esplorare quali altre opzioni ho. – user3015739

+1

Mi piacciono le soluzioni semplici –

7

È possibile creare una tabella temporanea come

'CREATE TABLE #Pattern (
     SearchItems VARCHAR(20) 
    );' 

Nota a margine: assicurarsi di verificare se la tabella temporanea esiste per evitare errori. Ora è possibile inserire i dati di ricerca per la tabella temporanea come

'INSERT 
    INTO #Pattern 
    VALUES 
     ('% APPLE %'), 
     ('% ORANGE %'), 
     ('% BANANA %');' 

Ora, usando questa tabella temporanea, Cerca il tuo tavolo utilizzando un INNER JOIN come

'SELECT * 
FROM Store 
INNER JOIN #Pattern 
    ON Store.Fruits LIKE SearchItems 
' 

Come nota, tabelle temporanee sono qualcosa Cerco di evitare soprattutto, ma qui è utile, e il caso che stavo usando questa soluzione non richiedeva prestazioni elevate. Piuttosto, ha reso più semplice mantenere gli oggetti di ricerca in costante crescita.

Spero che questo funzioni anche per gli altri.

-1

C'è un modo per farlo in SQL, ma è piuttosto complicato. Supponendo che tu possa convivere con una stringa che va fino a, ad esempio, tre nomi di frutta, procedi nel modo seguente.

si assume che @fruits è la variabile varchar contenente l'elenco dei frutti, a cui aggiungere altre delimitatori virgola (nel caso in cui esso contiene meno di tre nomi di frutta):

declare @fruits varchar(80); 
set @fruits = <list of fruits passed in> + ',_,_,_,'; 

Le seguenti equazioni non sono SQL , ma la matematica dietro le operazioni di sottostringa avremo bisogno per i like espressioni:

NOTE: NOT SQL 

First fruit word: 
p1 = charindex(',', @fruits)   << position of ',' delimiter 
v1 = substring(@fruits, 0, p1-1) + '%' << fruit word we seek 
r1 = substring(@fruits, p1+1)   << remainder of string 

Second fruit word:  
p2 = charindex(',', r1) 
v2 = substring(r1, 0, p2-1) + '%' 
r2 = substring(r1, p2+1) 

Third fruit word: 
p3 = charindex(',', r2) 
v3 = substring(r2, 0, p3-1) + '%' 
r3 = substring(r2, p3+1) 

...and so on... 

Ora sostituiamo i primi valori di p1, v1 e r1 nella seconda serie di equazioni per p2, e r2. Allo stesso modo, sostituiamo questi secondi valori nel terzo insieme e così via. Finiamo con queste mostruosità per v1, v2, e v3:

v1 = substring(@fruits, 0, charindex(',', @fruits)-1) + '%' 
v2 = substring(substring(@fruits, charindex(',', @fruits)+1), 0, charindex(',', substring(@fruits, charindex(',', @fruits)+1))-1) + '%' 
v3 = substring(substring(substring(@fruits, charindex(',', @fruits)+1), charindex(',', substring(@fruits, charindex(',', @fruits)+1))+1), 0, charindex(',', substring(substring(@fruits, charindex(',', @fruits)+1), charindex(',', substring(@fruits, charindex(',', @fruits)+1))+1))-1) + '%' 

Queste sono le prime tre LIKE valori che dobbiamo cercare:

select * from fruits 
where fruit like <v1> 
    or fruit like <v2> 
    or fruit like <v3> 

completamente espanso, la query è:

select * from fruits 
where fruit like substring(@fruits, 0, charindex(',', @fruits)-1) + '%' 
    or fruit like substring(substring(@fruits, charindex(',', @fruits)+1), 0, charindex(',', substring(@fruits, charindex(',', @fruits)+1))-1) + '%' 
    or fruit like substring(substring(substring(@fruits, charindex(',', @fruits)+1), charindex(',', substring(@fruits, charindex(',', @fruits)+1))+1), 0, charindex(',', substring(substring(@fruits, charindex(',', @fruits)+1), charindex(',', substring(@fruits, charindex(',', @fruits)+1))+1))-1) + '%' 

Possiamo fare più lavoro per estrarre la 4a parola, 5a parola, 6a parola e così via, per quanto ci piace. Ma ogni ulteriore valore di vN diventa molto più complicato del precedente.

Nota: non ho provato questa soluzione, l'ho provata solo matematicamente.

Problemi correlati