2010-06-21 9 views
15

ho questo tag tableINTERRUTTORE con LIKE all'interno query SELECT in 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'); 

Voglio recuperare tutti i record in cui tag corrisponde parole chiave class o pack o new, insieme ad un altro campo che indica quale delle 3 parole chiave effettivamente abbinato al campo del tag.

La seguente query non dare risultati corretti Query 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%" 

devo usare simili all'interno del case. Altrimenti lavori di abbinamento completi. La seguente query funziona: -

Query 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" 

Cosa c'è di sbagliato con la query 1. prega di aiuto.

+0

+1 per i dati DDL e di esempio – Unreason

+0

qual è il problema qui? La query 1 fornisce 11 risultati e ci sono 11 voci, che è ciò che ci si aspetterebbe. La clausola where nella query 2 è diversa e modifica il set di risultati. – Cez

+0

btw, puoi usare 'WHERE tag IN (" class "," new "," pack ")' – abatishchev

risposta

24

Mysql supporta due varianti di case, quella che si utilizza nella query 2 è meno flessibile ma supporta solo l'uguaglianza su una singola variabile. L'altra versione specifica nessuna variabile dopo caso e quindi le condizioni non deve essere solo l'uguaglianza:

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%" 

Vedi documentation per ulteriori dettagli

EDIT: Ecco un po 'più spiegazione sul motivo per cui la query # 1 ha restituito quello che tornato:

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

si aspetta di ottenere un valore letterale per il confronto tra when ... then Nel caso di cui sopra le espressioni tag LIKE "%class%", 0.123.e tag LIKE "%pack%" vengono tutti valutati prima del confronto case case. Tuttavia (!), Ciò che accade è che diventano 0 o 1 e rispetto al valore del tag è il primo valore di 0 che corrisponderà a qualsiasi char (il char verrà cast a 0) - questo è coerente con il risultati della tua prima domanda.

Ecco una query che mostra i valori logici per le espressioni rilevanti:

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%"; 

è per questo che si ottengono risultati inaspettati; il CAST silenzioso è una trappola standard qui.

+0

grazie mille! la risposta è abbastanza veloce –

+0

Grazie per la spiegazione estesa – Cez

6

Voglio solo ricordare, su altro clausola:

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