2009-02-10 30 views
5

Tengo una tabla como la siguiente:
MySQL búsqueda de varias columnas

 
+-------------------+---------------+ 
| description  | colour  | 
+-------------------+---------------+ 
| Macrame Dress  | Washed Black | 
| Darcelle Gilet | Dirty Shellac | 
| Darcelle Cardigan | Washed Black | 
| Let It Rot Vest | Optic White | 
| Let It Rot Crew | Washed Black | 
| Let It Rot Crew | Optic White | 
| Battalion Short | Somme   | 
| Seine Dress  | Washed Black | 
| Seine Dress  | Cocomotion | 
| Odette V-neck  | Linen Marl | 
+-------------------+---------------+ 
quiero buscarla para "vestido de negro" y sólo devuelve filas 1 & 8. Si el tipo de "negro", devolverá las filas 1 , 3, 5 & 8. el vestido debe devolver las filas 1, 8 & 9.

¿Puede alguien pensar en una muy elegante hermosa bits de SQL, que se llevará a cualquier número de palabras de búsqueda y devolver el conjunto de resultados más concisa. Puedo pensar en algunas formas bastante feas de hacerlo, pero alteraron mi karma.

Respuesta

0

Idealmente, creo que tendrías dos términos de búsqueda separados, uno para la descripción (s1) y otro para el color (s2).

A continuación, la consulta se convierte en:

select * from tbl where description like '%(s1)%' and colour like '%(s2)%' 

Sustituyendo en los valores de S1 y S2, por supuesto.

Una s2 en blanco daría como resultado un %% que debería coincidir con todo (creo).

Para poder buscar en varios términos, ya sea en el campo, se necesita algo así como

select * from tbl 
    where description + colour like '%(s1)%' 
     and description + colour like '%(s2)%' 
     and description + colour like '%(s3)%' 

Esto tendrá que ser construido sobre la marcha, con base en el número de palabras en su patrón de búsqueda (por lo que " el vestido negro "tendrá s1 y s2, negro solo tendrá s1). El bit "descripción + color" son campos concatenados; mi SQL está un poco oxidado, así que no sé cómo lo harías exactamente, pero el concepto es sólido.

+0

gracias Pax, pero creo que varios campos no encajan con una experiencia de usuario simple. Creo que un usuario debería poder escribir lo que sea y el código debería funcionar alrededor del usuario. Su solución multi-concat podría funcionar, es lo que inicialmente pensé, pero estaba buscando algo más elegante. –

+0

No hay problema, Stuart, pero eres un hombre difícil de complacer :-) Dado que tus limitaciones son pesadas (no se permiten cambios en las tablas), eso obstaculiza todas las respuestas posibles. Puede que tenga que elegir entre sus limitaciones y su elegancia deseada, dependiendo de cuál es más importante para usted. – paxdiablo

3

La única buena solución (karma-wise) que puedo pensar implicaría el uso de un índice FULLTEXT. Esto permitirá hacer uso de las consultas de la siguiente manera:

SELECT * FROM mytable 
WHERE MATCH (description,color) AGAINST ('black dress'); 

Desafortunadamente, los índices FULLTEXT requieren el tipo de tabla MyISAM, si no recuerdo mal.

EDITAR

Dudo que esto es lo que está buscando, pero permítanme añadir que por el bien de la discusión. Usted podría duplicar sus datos en una tabla MyISAM temporal y hacer búsqueda de texto completo en el que:

CREATE TEMPORARY TABLE mytmptable ENGINE=MyIsam SELECT * FROM mytable; 
ALTER TABLE mytmptable ADD FULLTEXT KEY (description,color); 
SELECT * FROM mytmptable WHERE MATCH (description,color) AGAINST ('black dress'); 
+0

lamentablemente no puedo cambiar el motor, debido a otras limitaciones de indexación y de transacción, pero sí, esta habría sido mi solución ideal. –

+0

¿Sabe que puede configurar el motor utilizado por mesa, ¿verdad? Por lo tanto, si tiene suerte y no tiene restricciones transaccionales en * esta tabla específica *, puede hacer que sea MyISAM sin afectar las otras tablas. [plugin redactado para PostgreSQL] – kquinn

+0

no, esta tabla tiene que ser innoDB, es la tabla de producto principal para el sitio y debe ser transaccional –

0

tipo ¿Qué datos son sus columnas? Si son VARCHAR o similares, que le hace simplemente

select 
    * 
from 
    tbl 
where 
    description like '%(s1)%' 
    or colour like '%(s1)%' 

(Esta es una adaptación de @Pax, que creo que entendido mal la pregunta - Me tomo como que significa que debe coincidir siempre que aparece el término de búsqueda en " . Descripción' o 'color')

+0

, esto arrojaría resultados si el color era como el negro o la descripción era como el vestido, pero Necesito solo devolver vestidos negros. es una Y, pero más de 2 columnas. Planeo usar un quirófano en una segunda consulta como parte de UNIÓN como retroceso –

1
where colour+description like '%s1%' 
+0

esa es la solución que se me ocurrió, pero me preocupa que "Vestido de macramé negro lavado" no sea compatible con "vestido negro" –

+0

luego tenemos que romper los dos términos de búsqueda y tener: donde color + descripción como '% s1%' y color + descripción como '% s2%' – Learning

+1

.. y por supuesto no se usarán índices y una tabla completa exploración seguirá. – Learning

0

Bueno, siempre y cuando se puede usar PHP para montar la consulta, esto debería funcionar:

SELECT * FROM tbl 
WHERE (description LIKE '%black%' OR colour LIKE '%black%') 
AND (description LIKE '%dress%' OR colour LIKE '%dress%') 

... donde se agrega uno de los corchetes condiciones para cada palabra en t el término de búsqueda, y conectarlos con "Y". Esto requiere una coincidencia en al menos una de las columnas para cada una de las palabras en el término de búsqueda.

No es SQL puro (la consulta real dependerá de la cantidad de palabras en el término de búsqueda), pero se siente razonablemente elegante y creo que debería hacer el trabajo.

0
$node=explode(" ",$keysearch); 
$sql="SELECT * FROM tbl_dress WHERE "; 
$x=0; 
foreach ($node as $key => $ns) { 
    $x++; 
    if ($x > 1){$sql.=" AND ";} 
    $sql.="(CONCAT(description, colour) LIKE '%$ns%')"; 
} 
Cuestiones relacionadas