2017-03-09 6 views
0

Ich muss eine Auswahlabfrage schreiben, die eine einzelne Tabelle nach Wörtern durchsucht, die aus einer Benutzereingabeabfragezeichenfolge wie "John Doe Engineering" stammen. Die Zeichenfolge kann aus einem einzelnen oder mehreren Wörtern bestehen. Die Abfragezeichenfolge wird als Parameter an eine gespeicherte Prozedur übergeben. Insgesamt gibt es ca. 20 Spalten, die durchsucht werden müssen. Mein erster Gedanke war so etwas wie diese:Abfrage auswählen, um mehreren Spalten mit mehreren Schlüsselwörtern zu entsprechen

SELECT * 
FROM Employees 
WHERE FirstName LIKE '%John%' OR FirstName LIKE '%Doe%' OR FirstName LIKE '%Engineering%' 
WHERE LastName LIKE '%John%' OR LastName LIKE '%Doe2%' OR LastName LIKE '%Engineering%' 
WHERE Manager LIKE '%John%' OR Manager LIKE '%Doe%'OR Manager LIKE '%Engineering%' 
WHERE Department LIKE '%John%' OR Department LIKE '%Doe%'OR Department LIKE '%Engineering%' 
--repeat for 16 more table columns 

Aber ich bin nicht sicher, wie man am besten die Abfragesyntax, wenn die Benutzer Query-String-Eingabe zu generieren. Außerdem scheint dies eine sehr ineffiziente Abfrage zu sein. Wäre es besser, in diesem Fall full text search zu verwenden? Ich frage mich, was der beste Ansatz sein könnte?

+1

SQL Server über eine Funktion zur Volltextsuche aufgerufen hat. Wahrscheinlich, was du hier willst. – Hogan

+1

Ich denke "Volltextsuche". –

+1

@GordonLinoff - Bis 3 Sekunden! : D – Hogan

Antwort

-1

Wie alle anderen sagten - Volltextsuche ist wahrscheinlich die beste Lösung für diese Art von Sache. Trotzdem dachte ich, es würde Spaß machen, eine T-SQL-Lösung anzubieten.

Schnell Haftungsausschluss 1

* ich stark fördern würden Sie nicht die Lösungen unten verwenden - dies wurde Übung ein wenig Spaß SQL sein soll; die Leistung wäre schlecht. Auch - ich zeigen zwei sehr effiziente Möglichkeiten, um einen String aufgeteilt werden: eine mit Jeff Moden des DelimitedSplit8K, die andere Technik ParseName *

Schnell Haftungsausschluss 2

ich ein Problem hinweisen, sollten die Spalten in eine mit verketten einzelne Saite als Paar vorgeschlagen - es kann zu falschen positiven führen; Sehen Sie die folgende Abfrage:

DECLARE @search varchar(100) = 'ab'; 

WITH sampleData AS (SELECT fn, ln FROM (VALUES ('aa', 'bb'), ('cc', 'dd')) t(fn,ln)) 
SELECT * 
FROM sampleData 
WHERE CONCAT(fn,ln) LIKE '%'[email protected]+'%'; 

Die obige Abfrage den ersten Datensatz zurück, obwohl die „ab“ existiert nicht in jeder Spalte. Aus diesem Grund würden Sie die WHERE (oder CHARINDEX in Johns Beispiel) ändern wie folgt aussehen:

WHERE CONCAT(fn, '|||', ln) LIKE '%'[email protected]+'%'; 

Meine Lösungen

-- SAMPLE DATA 
------------------------------------------------- 
DECLARE @employees TABLE 
(
    FirstName varchar(100), 
    LastName varchar(100), 
    Manager varchar(100), 
    Department varchar(100) 
); 

INSERT @employees 
SELECT * 
FROM 
(
    VALUES 
    ('bob', '****', 'ddd', 'sss'), 
    ('fff', 'fred', 'obx', 'ccc'), 
    ('Sue', 'abcd', 'ddd', 'zzz'), 
    ('ddd', 'dcba', '123', 'fobbb') 
) xx(x1, x2, x3, x4); 

-- Solution #1: when @search has <= 4 "items" 
------------------------------------------------- 
DECLARE @search varchar(100) = 'xx bb ff zz'; 

SELECT e.* 
    --,PARSENAME(REPLACE(@search,' ','.'), N) AS matchedPattern 
FROM (VALUES (1),(2),(3),(4)) t(n) 
CROSS JOIN @employees e 
WHERE 
    CHARINDEX 
    (
    PARSENAME(REPLACE(@search,' ','.'), N), 
    CONCAT(FirstName, '|||', LastName, '|||', Manager, '|||', Department) 
) > 0; 

-- Solution #2: when @search has (or can have) > 4 "items" 
------------------------------------------------- 

-- for this you will need delimitedsplit8k: http://www.sqlservercentral.com/articles/Tally+Table/72993/ 
SELECT e.* 
FROM dbo.delimitedsplit8k(@search, ' ') 
CROSS JOIN @employees e 
WHERE 
    CHARINDEX 
    (
    item, 
    CONCAT(FirstName, '|||', LastName, '|||', Manager, '|||', Department) 
) > 0; 
+0

die Idee der Kombination der Spalten ist schrecklich. Es wird eine langsame Leistung verursachen. Wie ich in meinem Kommentar erwähnt –

+0

@ t-clausen.dk - das ist, warum ich sagte "Volltextsuche ist wahrscheinlich die beste Lösung" dann fügte hinzu, dass ich eine T-SQL-Lösung "zum Spaß." Sie haben nichts anderes als einen Kommentar angeboten, den alle hier, einschließlich der OP, bereits wussten. Ich werde an der Lösung interessiert sein, die du postest ... –

+0

du stimmst tatsächlich meine [Antwort] ab (http://stackoverflow.com/questions/42509024/get-string-between-2-characters-that- wiederhole-mehrere-mal-in-sql-server/42509706 # comment72537334_42509706) auf eine andere Frage in Rache von mir unten, dies zu wählen? –

Verwandte Themen