2012-05-15 13 views
9

¿Hay algún método para usar contener en lugar de igual en el enunciado caso?CASO (Contiene) en lugar de la declaración igual

Por ejemplo, estoy comprobando una tabla de base de datos tiene una entrada

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

¿Puedo usar

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

Esto no funcionó.

Gracias de antemano

Respuesta

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

El líder ', ' y posterior ',' se añaden para que pueda manejar el partido, independientemente de dónde se encuentra en la cadena (primera entrada, la última entrada, o en cualquier lugar en el medio).

Dicho esto, ¿por qué está almacenando los datos que desea buscar como una cadena separada por comas? Esto viola todo tipo de formas y mejores prácticas. Debería considerar normalizar su esquema.

Además: no utilice 'single quotes' como delimitadores de identificador; esta sintaxis está en desuso. Use [square brackets] (preferido) o "double quotes" si es necesario. Consulte "literales de cadena como alias de columna" aquí: http://msdn.microsoft.com/en-us/library/bb510662%28SQL.100%29.aspx

EDITAR Si tiene varios valores, puede hacer esto (no se puede taquigrafía esto con la otra variante CASE de sintaxis o mediante el uso de algo así como IN()) :

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

Si tiene más valores, podría valer la pena utilizar una función dividida, por ejemplo

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 

Resultados:

ID 
---- 
1 
2 
4 
+0

Esto funciona muy bien, gracias por los consejos sobre la normalización, va a hacer. ¿Hay alguna forma de agregar O a la instrucción, por ejemplo LIKE '%, lactulose,%' OR '% amlodipine%'. Gracias de nuevo – hncl

+0

Sí solo CASE CUANDO ... COMO ... O ... ME GUSTA ... no puedes hacerlo sin repetir la primera expresión. Voy a publicar un ejemplo más adelante que trata con múltiples valores. –

+0

Gracias Aaron, esto es muy útil. – hncl

4

Pseudo código, algo así como:

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

Esto no le importa donde la palabra clave se encuentra en la lista y evita en función de formateo de espacios y comas .

+0

Bueno, primero Instr es de VB y no de SQL. Además, "no importar" el formato, los espacios y las comas significa que obtendrá falsos positivos si la cadena es ''bipolar, bilactulosa, foo'' ... –

+0

Acordado sobre falsos positivos en caso de que la palabra clave sea una subcadena de un dato palabra. La forma de evitar esto (aparte de una normalización adecuada) es usar un separador que sea más obvio que ','; tal vez '|' o '@'. – Bilbo

+0

Arenque rojo. El separador no es lo que causaría un falso positivo con su solución. Observe cómo obtendría '' BP Medication'' para la fila que contiene ''bilactulosa'' aunque esa fila no contenga la palabra que está buscando (' 'lactulosa''). No creo que la intención del OP sea hacer coincidir palabras parciales. –

Cuestiones relacionadas