2010-06-21 19 views
15

he éste Etiquetas de mesaconmutador con gusto dentro consulta SELECT en MySQL

CREATE TABLE IF NOT EXISTS `Tags` (
    `id_tag` int(10) unsigned NOT NULL auto_increment, 
    `tag` varchar(255) default NULL, 
    PRIMARY KEY (`id_tag`), 
    UNIQUE KEY `tag` (`tag`), 
    KEY `id_tag` (`id_tag`), 
    KEY `tag_2` (`tag`), 
    KEY `tag_3` (`tag`), 
    KEY `tag_4` (`tag`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=2937 ; 

INSERT INTO `Tags` (`id_tag`, `tag`) VALUES 
    (1816, '(class'), 
    (2642, 'class\r\n\r\nâ?¬35'), 
    (1906, 'class\r\nif'), 
    (1398, 'class'), 
    (2436, 'class)'), 
    (1973, 'class:\n1.'), 
    (2791, 'classes'), 
    (1325, 'New'), 
    (2185, 'pack'), 
    (1905, 'packed'), 
    (1389, 'WebClass'); 

quiero ir a buscar todos los registros en los que la etiqueta coincide con palabras clave class o pack o new, junto con otro campo que indica cuál de las 3 palabras clave en realidad coincide con el campo de etiqueta.

la siguiente consulta no da resultados correctos Consulta 1

select id_tag, 
case tag 
    when tag LIKE "%class%" then "class" 
    when tag LIKE "%new%" then "new" 
    when tag LIKE "%pack%" then "pack" 
end as matching_tag 
from Tags 
where tag LIKE "%class%" OR tag LIKE "%new%" OR tag LIKE "%pack%" 

tengo que usar similares dentro de la caja. De lo contrario, la coincidencia completa funciona. La siguiente consulta funciona: -

Consulta 2

select id_tag, 
case tag 
    when "class" then "class" 
    when "new" then "new" 
    when "pack" then "pack" 
end as matching_tag 
from Tags 
where tag = "class" OR tag = "new" OR tag = "pack" 

Lo que está mal con la consulta 1. Por favor, ayuda.

+0

+1 para los datos DDL y de la muestra – Unreason

+0

Cuál es el problema aquí? La consulta 1 da 11 resultados y hay 11 entradas, que es lo que se esperaría. La cláusula where en la consulta 2 es diferente y cambia el conjunto de resultados. – Cez

+0

Por cierto, puede usar 'WHERE tag IN (" clase "," nuevo "," paquete ")' – abatishchev

Respuesta

24

Mysql admite dos variantes de mayúsculas y minúsculas, la que utiliza en la consulta 2 es menos flexible pero solo admite igualdad en una sola variable. La otra versión especifica ninguna variable después del caso y luego las condiciones no tiene por qué ser sólo la igualdad:

select id_tag, 
case 
    when tag LIKE "%class%" then "class" 
    when tag LIKE "%new%" then "new" 
    when tag LIKE "%pack%" then "pack" 
end as matching_tag 
from Tags 
where tag LIKE "%class%" OR tag LIKE "%new%" OR tag LIKE "%pack%" 

Ver documentation para más detalles

EDIT: Aquí hay un poco más de explicación sobre por qué su consulta # 1 devuelve lo que devueltos:

case tag 
    when tag LIKE "%class%" then "class" 
    when tag LIKE "%new%" then "new" 
    when tag LIKE "%pack%" then "pack" 
end as matching_tag 

espera para obtener un valor literal para la comparación entre when ... then En el caso anterior las expresiones tag LIKE "%class%", tag LIKE "%new%" y tag LIKE "%pack%" son todos evaluados antes de la comparación de casos reales. Sin embargo (!), Lo que pasa es que se vuelven 0 o 1 y cuando se compara con el valor de la etiqueta es el primer valor de 0 que coincidirá con cualquier char (char se lanzará a 0) - esto es consistente con resultados de su primera consulta.

Aquí es una consulta que muestra los valores lógicos de las expresiones relevantes:

select id_tag, tag LIKE "%class%", tag LIKE "%new%", tag = 0, case tag  when tag LIKE "%class%" then "class"  when tag LIKE "%new%" then "new" when tag LIKE "%pack%" then "pack" end as matching_tag from Tags where tag LIKE "%class%" OR tag LIKE "%new%" OR tag LIKE "%pack%"; 

Es por eso que se obtienen resultados inesperados; el CAST silencioso es una trampa estándar aquí.

+0

muchas gracias! obtuvo la respuesta bastante rápido –

+0

Gracias por la explicación ampliada – Cez

6

sólo quiero recordar, sobre otra cláusula:

case 
    when tag LIKE "%class%" then "class" 
    when tag LIKE "%new%" then "new" 
    when tag LIKE "%pack%" then "pack" 
    else "no one" 
end as matching_tag 
Cuestiones relacionadas