TSQL-Variable Mit Liste von Werten für die IN-Klausel
Möchte ich die Verwendung einer Klausel, die entlang der Linien von "CASE WHEN ... then 1 ELSE 0 END" in einer select-Anweisung. Der schwierige Teil ist, dass ich es brauche, mit zu arbeiten "- Wert IM @List".
Wenn ich hart code in der Liste funktioniert es - und es funktioniert gut:
SELECT
CASE WHEN t.column_a IN ( 'value a', 'value b' ) THEN 1 ELSE 0 END AS priority
, t.column_b
, t.column_c
FROM
table AS t
ORDER BY
priority DESC
Was ich tun möchte ist:
-- @AvailableValues would be a list (array) of strings.
DECLARE
@AvailableValues ???
SELECT
@AvailableValues = ???
FROM
lookup_table
SELECT
CASE WHEN t.column_a IN @AvailableValues THEN 1 ELSE 0 END AS priority
, t.column_b
, t.column_c
FROM
table AS t
ORDER BY
priority DESC
Leider, es scheint, dass der SQL Server dies nicht tut, können Sie nicht verwenden Sie eine variable mit einer IN-Klausel. So lässt mich das mit einigen anderen Optionen:
- Machen '@AvailableValues' eine durch Komma getrennte Zeichenfolge und verwenden Sie eine LIKE-Anweisung. Dies funktioniert nicht besonders gut.
- Die Verwendung einer inline-SELECT-Anweisung gegen das 'lookup_table' an die Stelle der variable. Wieder, nicht gut (denke ich), weil es um die lookup-Tabelle in jeder Zeile.
- Eine Funktion schreiben, die Verpackung um die SELECT-Anweisung anstelle der variable. Ich habe dies noch nicht ausprobiert (werde es jetzt versuchen), aber es scheint, dass es das gleiche problem, wie eine direct SELECT-Anweisung.
- ???
Gibt es andere Optionen? Leistung ist sehr wichtig für die Abfrage - es hat wirklich schnell sein, wie es ernährt einen Echtzeit-such-Ergebnis-Seite (also kein caching) für eine web-site.
Gibt es andere Optionen hier? Gibt es eine Möglichkeit zur Verbesserung der Leistung von einer der oben genannten Optionen, um auch gute Leistung?
Vielen Dank im Voraus für jede Hilfe!
UPDATE: ich sollte erwähnt haben, dass die "lookup_table' im obigen Beispiel ist bereits eine table-variable. Ich habe auch aktualisiert, die Probe Abfragen, um besser zu zeigen wie ich bin, mit der Klausel.
UPDATE II: Es fiel mir ein, dass die IN-Klausel ist in Betrieb off eine NVARCHAR-NCHAR Feld (wegen der historischen Tabelle design-Gründen). Wenn ich änderungen an, die sich mit integer-Felder (ich.e durch PK/FK-Beziehungen Einschränkungen), könnte dies große Auswirkungen auf die performance?
- Werfen Sie einen Blick auf Erland Sommarskog den Artikel hier: Arrays und Listen im SQL Server 2005 und darüber Hinaus Für die Jahre 2000 und 2008-Versionen, schau mal hier: sommarskog.se/arrays-in-sql.html
- Musst mehr Los hier als
SELECT count(*) from MyTable where MyColumn in (select LookupValue from LookupTable)
. Poste die vollständige Abfrage und jemand wird Ihnen helfen zu optimieren. - bereits mit Hilfe der Tabelle Variablen in der SP, hatte performance Probleme hier.
- Kelly, ich habe Beispiele wurden aktualisiert, um widerzuspiegeln, was ich versuche zu tun, besser.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Können Sie eine variable in einer
IN
- Klausel, nicht aber in der Art und Weise Sie zu tun versuchen. Zum Beispiel, Sie könnten dies tun:Der Schlüssel ist, dass die Variablen nicht darstellen kann, mehr als einen Wert.
Ihre Frage zu beantworten, verwenden Sie die inline-wählen. Solange Sie nicht einen äußeren Wert in der Abfrage (was könnte sich ändern, die Ergebnisse auf einer pro-Zeilen-basis), der Motor wird nicht wiederholt die gleichen Daten selektiert aus der Tabelle.
Basierend auf Ihrem update-und vorausgesetzt, die lookup-Tabelle klein ist, schlage ich vor, versuchen so etwas wie die folgenden:
(Man kann nicht auf die Spalte verweisen, alias "Priorität" in der ORDER BY-Klausel. Alternativ können Sie die Ordinalposition etwa so:
aber das ist in der Regel nicht empfohlen.)
Solange die lookup-Tabelle ist klein , das wirklich laufen sollte ziemlich schnell-aber dein Kommentar impliziert, dass es eine ziemlich große Tabelle, und das könnte sich verlangsamen Leistung.
Als für n[Var]char gegen int, ja, ganze zahlen wäre schneller, wenn auch nur, weil die CPU hat weniger bytes zu jonglieren, um... das sollte nur ein problem bei der Verarbeitung einer viel von Zeilen, so könnte es einen Versuch Wert.
Diese könnte entlang der Linien von, was Sie brauchen.
Beachten Sie, dass hier davon ausgegangen, dass Sie über die Berechtigungen und die input-Daten wurden bereinigt.
Vom Ausführen Gespeicherte Prozeduren Dynamische
Löste ich dieses problem durch die Verwendung eines CHARINDEX-Funktion. Ich wollte den string als einzigen parameter. Ich erstellt einen string mit führenden und nachgestellten Kommas für jeden Wert, den ich für den test wollte. Dann habe ich verkettet einer der führenden und nachgestellten Kommas, um die Zeichenfolge, die ich wollte sehen, ob war "in" - parameter. Am Ende habe ich überprüft, die CHARINDEX - > 0
Kann man es auch in der where-Klausel
Wenn Sie versuchen zu vergleichen, die zahlen, die Sie bräuchte, um die Zahl zu konvertieren, um eine Zeichenfolge für die CHARINDEX-Funktion zu arbeiten.