2012-05-15 10 views
9

Esiste un metodo per utilizzare contenere piuttosto che uguale nell'istruzione case?CASO (Contiene) piuttosto che la dichiarazione uguale

Per esempio, sto controllando una tabella di database ha una voce

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

Posso usare

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

Ciò non ha funzionato.

Grazie in anticipo

risposta

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

Il leader ', ' e finali ',' sono aggiunti in modo da poter gestire la partita indipendentemente da dove si trova nella stringa (prima voce, ultima voce, o dovunque nel fratempo).

Detto questo, perché si memorizzano i dati su cui si desidera eseguire la ricerca come stringa separata da virgole? Ciò viola tutti i tipi di forme e best practice. Dovresti considerare di normalizzare il tuo schema.

Inoltre: non utilizzare 'single quotes' come delimitatori identificatori; questa sintassi è deprecata. Utilizzare [square brackets] (preferito) o "double quotes" se necessario. Vedere "stringhe letterali come alias di colonna" qui: http://msdn.microsoft.com/en-us/library/bb510662%28SQL.100%29.aspx

EDIT Se si dispone di più valori, si può fare questo (non è possibile a breve mano questo con l'altra variante CASE sintassi o usando qualcosa come IN()) :

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

Se si dispone di più valori, potrebbe essere utile utilizzare una funzione di divisione, ad es.

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 

Risultati:

ID 
---- 
1 
2 
4 
+0

Questo funziona benissimo, grazie per il consiglio sulla normalizzazione, lo farà. C'è un modo per aggiungere OR all'istruzione, ad esempio LIKE '%, lattulose,%' OR '% amlodipine%'. Grazie ancora – hncl

+0

Sì, solo CASO QUANDO ... MI PIACE ... O ... MI PIACE ... non puoi farlo senza ripetere la prima espressione. Pubblicherò un esempio più tardi che si occupa di più valori. –

+0

Grazie Aaron, questo è molto utile. – hncl

4

Pseudo codice, qualcosa di simile:

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

Questo non si cura, dove la parola chiave si trova nella lista ed evita seconda formattazione degli spazi e virgole .

+0

Ben prima Instr è da VB e non SQL. Inoltre per "non preoccuparti" di formattazione, spazi e virgole significa che otterrai falsi positivi se la stringa è "bipolare, bilattulosio, foo" ... –

+0

Concordato sui falsi positivi nel caso in cui la parola chiave sia una sottostringa di un dato- parola. Il modo per evitarlo (oltre alla normale normalizzazione) è usare un separatore più ovvio di ","; forse '|' o '@'. – Bilbo

+0

Aringhe rosse. Il separatore non è ciò che causerebbe un falso positivo con la tua soluzione. Notate come otterreste "Farmaci BP" per la riga che contiene "bilattulosio" anche se quella riga non contiene la parola che state cercando ("lattulosio")? Non penso che l'OP abbia l'intenzione di abbinare parole parziali. –

Problemi correlati