2014-10-29 3 views
6

Ich möchte Ihren Rat suchen, ob irgendeine Funktion in SQL Server, die mir erlauben, Teilübereinstimmung für eine Liste von Werten durchzuführen?TSQL - Partial Matching mit LIKE für mehrere Werte

Die gesamte Zeichenfolge, die abgeglichen werden muss, wird über die Speicherprozedur übergeben.

Ich versuche, eine andere Alternative zu finden, bevor ich meine eigene Funktion schreibe, um die Zeichenkette durch Komma zu teilen und dann alle Ergebnisse zu vereinigen, bevor die Daten an das Programm zurückgegeben werden.

Zum Beispiel würde ich in der folgenden Zeichenfolge in meine TSQL

Apfel, Orange, Birne

in meiner WHERE Klausel übergibt es

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

entsprechen sollten Kann ich die obigen Ergebnisse in einer einzigen SQL-Anweisung erreichen, anstatt eine Funktion zu schreiben, um jede Zeichenkette zu unterbrechen?

Daten in meiner Tabelle

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

Also, wenn ich in der Zeichenfolge "Apfel, Birne" bestanden, muss ich zurück

apple red 
apple green 
pear big 
pear small 
+2

Wie sieht 'fruits' aus? Sagen Sie keine durch Kommas getrennten Werte. Das ist ein sehr, sehr schlechter Entwurf für eine relationale Datenbank. –

+0

Ich benutze nur eine einfache Tabelle zur Veranschaulichung. – user3015739

+0

Sie haben ein grundlegendes Problem mit Ihrer Datenstruktur. Sie sollten keine Listen von Dingen als Strings speichern. Stattdessen sollten Sie eine Junction-Tabelle verwenden. –

Antwort

1

dies versuchen, aber die Leistung nicht gut sein

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

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

Es hat nicht funktioniert, weil Sie nicht Apfel, Orange in den gleichen Daten haben können. Ich benutze nur Pattern Matching, um alle Apfel rot, Apfelgrün, Orange groß, Orange klein zu finden. – user3015739

+0

Sorry, geben Sie - Ich habe die Parameter umgekehrt.Versuchen Sie die geänderte Version – Sparky

1

Es könnte so einfach sein wie:

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

Die Zeichenfolge wird von einer Speicherprozedur übergeben und ich muss den Datensatz mithilfe Mustererkennung zurückgeben. Ich habe kein Problem, eine Funktion zu schreiben, um die Zeichenfolge zu teilen und dann die Ergebnisse zu vereinigen. Versuche einfach herauszufinden, welche anderen Möglichkeiten ich habe. – user3015739

+1

Ich mag einfache Lösungen –

7

Sie eine temporäre Tabelle als

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

Randnotiz: Überprüfen Sie, ob die temporäre Tabelle vorhanden ist, um Fehler zu vermeiden. Jetzt können Sie Ihre Suchbegriffe in der temporären Tabelle als

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

nun mit dieser temporären Tabelle einfügen, Suchen Sie Ihren Tisch

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

Als Hinweis eines INNER JOIN wie Verwendung von Temp Tables ist etwas Ich versuche es meistens zu vermeiden, aber hier ist es praktisch, und der Fall, in dem ich diese Lösung verwendete, war nicht anspruchsvoll. Vielmehr wurde es einfacher, die immer größer werdenden searchItems zu pflegen.

Hoffe, das funktioniert auch für andere.

-1

Es gibt einen Weg, es in SQL zu tun, aber es ist ziemlich kompliziert. Angenommen, Sie können mit einer Übereinstimmung von beispielsweise bis zu drei Obstnamen leben, gehen Sie folgendermaßen vor.

Wir gehen davon aus, dass @fruits ist die varchar Variable die Liste der Früchte enthält, auf die wir mehr Komma Trennzeichen anhängen (falls es enthält weniger als drei Obstnamen):

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

Die folgenden Gleichungen nicht SQL sind , aber die Mathematik hinter der Teilzeichenfolge Operationen, die wir für die like Ausdrücke benötigen:

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... 

wir nun die ersten Werte von p1 ersetzen, v1 und r1 in den zweiten Satz von Gleichungen für p2, v2 und r2. Und ebenso ersetzen wir diese zweiten Werte in die dritte Menge und so weiter. Wir am Ende mit diesen Ungeheuerlichkeiten für v1, v2 und 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) + '%' 

Dies sind die ersten drei LIKE Werte, die wir brauchen, suchen:

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

Vollständig erweitert, die Abfrage ist:

Wir können mehr Arbeit tun, um das 4. Wort, 5. Wort, 6. Wort und so weiter zu extrahieren, so weit wir wollen. Aber jeder weitere vN Wert wird weit komplizierter als der vorherige.

Hinweis: Ich habe diese Lösung nicht ausprobiert, ich habe es nur mathematisch bewiesen.