2012-05-15 11 views
9

Gibt es eine Methode, die in case-Anweisungen contain und nicht gleich ist?CASE (Enthält) anstelle von equal-Anweisung

Zum Beispiel bin ich eine Datenbanktabelle überprüft hat einen Eintrag

lactulose, Lasix (furosemide), oxazepam, propranolol, rabeprazole, sertraline, 

Kann ich

CASE When dbo.Table.Column = 'lactulose' Then 'BP Medication' ELSE '' END AS 'BP Medication' 

verwenden Dies hat nicht funktioniert.

Vielen Dank im Voraus

Antwort

16
CASE WHEN ', ' + dbo.Table.Column +',' LIKE '%, lactulose,%' 
    THEN 'BP Medication' ELSE '' END AS [BP Medication] 

Die führenden ', ' und ',' nachlauf hinzugefügt werden, so dass Sie das Spiel umgehen können, unabhängig davon, wo es in der Zeichenfolge (erster Eintrag, letzter Eintrag, oder irgendwo dazwischen).

Das heißt, warum speichern Sie Daten, die Sie durchsuchen möchten, als eine durch Komma getrennte Zeichenfolge? Dies verletzt alle Arten von Formen und Best Practices. Sie sollten in Betracht ziehen, Ihr Schema zu normalisieren.

Zusätzlich: 'single quotes' nicht als Bezeichnertrennzeichen verwenden; Diese Syntax ist veraltet. Verwenden Sie (bevorzugt) oder "double quotes", wenn Sie müssen. Siehe „Stringliterale als Spaltenaliasnamen“ hier: http://msdn.microsoft.com/en-us/library/bb510662%28SQL.100%29.aspx

EDIT Wenn Sie mehrere Werte haben, können Sie dies tun (man kann nicht kurz Hand dies mit der anderen CASE Syntaxvariante oder durch so etwas wie IN() verwenden) :

CASE 
    WHEN ', ' + dbo.Table.Column +',' LIKE '%, lactulose,%' 
    WHEN ', ' + dbo.Table.Column +',' LIKE '%, amlodipine,%' 
    THEN 'BP Medication' ELSE '' END AS [BP Medication] 

Wenn Sie mehrere Werte haben, kann es sinnvoll sein, eine Split-Funktion zu verwenden, z

USE tempdb; 
GO 

CREATE FUNCTION dbo.SplitStrings(@List NVARCHAR(MAX)) 
RETURNS TABLE 
AS 
    RETURN (SELECT DISTINCT Item FROM 
     (SELECT Item = x.i.value('(./text())[1]', 'nvarchar(max)') 
     FROM (SELECT [XML] = CONVERT(XML, '<i>' 
     + REPLACE(@List,',', '</i><i>') + '</i>').query('.') 
      ) AS a CROSS APPLY [XML].nodes('i') AS x(i)) AS y 
     WHERE Item IS NOT NULL 
    ); 
GO 

CREATE TABLE dbo.[Table](ID INT, [Column] VARCHAR(255)); 
GO 

INSERT dbo.[Table] VALUES 
(1,'lactulose, Lasix (furosemide), oxazepam, propranolol, rabeprazole, sertraline,'), 
(2,'lactulite, Lasix (furosemide), lactulose, propranolol, rabeprazole, sertraline,'), 
(3,'lactulite, Lasix (furosemide), oxazepam, propranolol, rabeprazole, sertraline,'), 
(4,'lactulite, Lasix (furosemide), lactulose, amlodipine, rabeprazole, sertraline,'); 

SELECT t.ID 
    FROM dbo.[Table] AS t 
    INNER JOIN dbo.SplitStrings('lactulose,amlodipine') AS s 
    ON ', ' + t.[Column] + ',' LIKE '%, ' + s.Item + ',%' 
    GROUP BY t.ID; 
GO 

Ergebnisse:

ID 
---- 
1 
2 
4 
+0

Das klappt super, danke für den Hinweis zur Normalisierung, wird reichen. Gibt es eine Möglichkeit, der Anweisung OR hinzuzufügen, zum Beispiel LIKE '%, Lactulose,%' ODER '% Amlodipin%'. Nochmals vielen Dank – hncl

+0

Ja, nur CASE WENN ... WIE ... ODER ... WIE ... Sie können es nicht tun, ohne den ersten Ausdruck zu wiederholen. Ich werde später ein Beispiel veröffentlichen, das sich mit mehreren Werten befasst. –

+0

Danke Aaron, das ist sehr hilfreich. – hncl

4

Pseudo-Code, so etwas wie:

CASE 
    When CHARINDEX('lactulose', dbo.Table.Column) > 0 Then 'BP Medication' 
ELSE '' 
END AS 'Medication Type' 

Diese kümmert sich nicht darum, wo das Schlüsselwort in der Liste gefunden wird, und vermeidet je nach Formatierung von Räumen und Komma .

+0

Nun zuerst Instr ist von VB und nicht SQL. Um sich auch nicht um die Formatierung zu kümmern, bedeutet Leerzeichen und Kommas, dass Sie falsch positive Ergebnisse erhalten, wenn der String "bipolar, bilactulose, foo" ist. –

+0

Vereinbarte über falsch positive Ergebnisse, wenn das Schlüsselwort ein Teilstring eines Daten- Wort. Der Weg, dies zu vermeiden (abgesehen von der richtigen Normalisierung), besteht darin, ein Trennzeichen zu verwenden, das offensichtlicher ist als ","; vielleicht '|' oder '@'. – Bilbo

+0

Roter Hering. Das Trennzeichen ist nicht das, was zu einem falschen Positiv mit Ihrer Lösung führen würde. Beachten Sie, wie Sie "BP Medication" für die Zeile erhalten würden, die "bilactulose" enthält, obwohl diese Zeile nicht das Wort enthält, nach dem Sie suchen ("Lactulose")? Ich glaube nicht, dass die OP beabsichtigt, Teilwörter zu vergleichen. –