2011-12-27 20 views
26

Tengo una consulta de mysql bastante complicada para mí, en la que estoy totalmente estancado y no encuentro ninguna respuesta en línea.consulta sql con múltiples instrucciones where

Aquí es mi consulta:

SELECT 
items.* 
FROM 
items 
INNER JOIN 
items_meta_data 
WHERE 
(
     (meta_key = 'lat' AND meta_value >= '55') 
    OR 
     (meta_key = 'lat' AND meta_value <= '65') 
) 
AND 
(
     (meta_key = 'long' AND meta_value >= '20') 
    OR 
     (meta_key = 'long' AND meta_value <= '30') 
) 
GROUP BY 
item_id 

Por supuesto, he probado la consulta con sólo 1 declaración y que funciona bien. Entonces, si solo paso la parte larga o lat entonces obtengo resultados. Solo cuando trato de unirlos obtengo resultados diferentes.

Gracias por la ayuda con anticipación!

La estructura de la tabla es la siguiente:

artículos de mesa: ID item_name Item_description

meta Tabla: meta_id item_id meta_key meta_value

Solución

A quien le interese finalmente logré enfrentar este problema. Gracias a todos por su ayuda y por dentro.

SELECT 
SQL_CALC_FOUND_ROWS items.* 
FROM 
items 
INNER JOIN 
items_meta ON (items.ID = items_meta.post_id) 
INNER JOIN 
items_meta AS m1 ON (items.ID = m1.post_id) 
WHERE 
1=1 
AND 
items.post_type = 'post' 
AND 
(items.post_status = 'publish') 
AND 
((items_meta.meta_key = 'lat' AND CAST(items_meta.meta_value AS SIGNED) BETWEEN '55' AND '65') 
AND 
(m1.meta_key = 'long' AND CAST(m1.meta_value AS SIGNED) BETWEEN '20' AND '30')) 
GROUP BY 
items.ID 
ORDER BY 
items.date 
DESC 
+1

¿Puede aclarar específicamente qué sucede cuando "los une"? ¿Cómo son los datos que está consultando y qué resultados obtiene? – David

+1

Podemos suponer que esto no es un error en mysql, por lo que debe decir lo que esperaba y lo que en su lugar observó. ¿Qué datos está poniendo a través de la consulta? – tenfour

+2

Está buscando una fila de la base de datos donde 'meta_key' es tanto' 'lat'' como' 'long''. No estoy seguro de que sea posible ... – lonesomeday

Respuesta

18

Debe tener en cuenta que GROUP BY se produce después de que se hayan evaluado las condiciones de la cláusula WHERE. Y la cláusula WHERE siempre considera solo una fila, lo que significa que en su consulta, las condiciones meta_key siempre evitarán que se seleccione cualquier registro, ya que una columna no puede tener múltiples valores para una fila.

¿Y qué ocurre con las comprobaciones meta_value redundantes? Si se permite que un valor sea tanto menor como mayor que un valor dado, entonces su valor real no importa en absoluto; la verificación puede omitirse.

De acuerdo con uno de sus comentarios, usted quiere verificar los lugares a menos de cierta distancia de una ubicación determinada. Para obtener las distancias correctas, en realidad tendría que utilizar algún tipo de función de distancia adecuada (consulte, por ejemplo, this question para obtener más información). Pero este SQL debería darle una idea de cómo comenzar:

SELECT items.* FROM items i, meta_data m1, meta_data m2 
    WHERE i.item_id = m1.item_id and i.item_id = m2.item_id 
    AND m1.meta_key = 'lat' AND m1.meta_value >= 55 AND m1.meta_value <= 65 
    AND m2.meta_key = 'lng' AND m2.meta_value >= 20 AND m2.meta_value <= 30 
+0

Probablemente sea donde está mi error. Necesito encontrar los artículos a una distancia de aproximadamente 10 km de la ubicación actual. Para las pruebas agregué las coordenadas actuales a la consulta. Esos deberían ser 5 km más pequeños que la ubicación actual y 5 km más grandes que la ubicación actual. – user1117774

+0

Aaah, eso es esclarecedor. Pero ¿por qué entonces comparar dos veces con el mismo valor? Lo que necesitarás es una unión doble, una para el latín y otra para el valor lat, intentaré trabajarlo en mi respuesta – codeling

+0

Sí, estoy tan desordenado después de luchar con esto durante horas que me resulta difícil de explicar. ¡Gracias por su paciencia! Cambié mi consulta de publicación inicial para que coincida más con lo que busco ... Lo editaré un poco más para obtener una vista más completa. – user1117774

3

Este ..

(
     (meta_key = 'lat' AND meta_value >= '60.23457047672217') 
    OR 
     (meta_key = 'lat' AND meta_value <= '60.23457047672217') 
) 

es lo mismo que

(
     (meta_key = 'lat') 
) 

Añadiendo que todos juntos (lo mismo se aplica al filtro long) que tenga esta cláusula WHERE imposible que dará no hay filas porque meta_key no pueden ser 2 valores en una fila

WHERE 
    (meta_key = 'lat' AND meta_key = 'long') 

Es necesario revisar sus operadores para asegurarse de obtener la lógica correcta

+0

Esto no es verdad. Cada elemento tiene múltiples filas de metadatos en la meta tabla. Así que estoy buscando artículos que coincidan con múltiples coincidencias. – user1117774

+0

@ user1117774: sí. es verdad. La lógica dicta su DONDE está equivocado – gbn

+0

Cada ítem en los ítems de la tabla tiene múltiples filas de metadatos asociadas desde la metatabla. Por ejemplo, el elemento con ID = 1 tiene en la tabla meta las siguientes filas asociadas: rowID = 1, itemID = 1, meta_key = lat, meta_value = '1234' rowID = 2, itemID = 1, meta_ket = long, meta_valye = '5678' – user1117774

0

¿Cuál es meta_key? Franja de formularios de todos los meta_value condicionales, reducir, y se termina con esto:

SELECT 
* 
FROM 
meta_data 
WHERE 
(
     (meta_key = 'lat') 
) 
AND 
(
     (meta_key = 'long') 
) 
GROUP BY 
item_id 

Desde meta_key puede, no se devolverán resultados nunca al mismo tiempo la igualdad de dos valores diferentes.


Sobre la base de los comentarios a través de esta pregunta y respuestas hasta el momento, parece que usted está buscando algo más en la línea de este:

SELECT 
* 
FROM 
meta_data 
WHERE 
(
    (meta_key = 'lat') 
    AND 
    (
     (meta_value >= '60.23457047672217') 
     OR 
     (meta_value <= '60.23457047672217') 
    ) 
) 
OR 
(
    (meta_key = 'long') 
    AND 
    (
     (meta_value >= '24.879140853881836') 
     OR 
     (meta_value <= '24.879140853881836') 
    ) 
) 
GROUP BY 
item_id 

Nota del OR entre las condicionales de primer nivel . Esto se debe a que desea registros que son latolong, ya que no solo registro será nunca lat y long.

Todavía no estoy seguro de lo que estás tratando de lograr con los condicionales internos. Cualquier valor no nulo coincidirá con esos números. Entonces tal vez puedas dar más detalles sobre lo que estás tratando de hacer allí. Tampoco estoy seguro del propósito de la cláusula GROUP BY, pero eso podría estar fuera del contexto de esta pregunta por completo.

+0

Hay varias filas con metadatos por artículo ... – user1117774

+0

@ user1117774: Pero ninguna fila coincidirá con esta consulta. ¿Tal vez quiere que el 'AND' en la versión reducida sea un' OR'?Actualice la pregunta con la estructura de la tabla y podemos ayudar a crear una consulta. – David

+0

La consulta debe coincidir con 2 filas de la meta tabla por elemento para que sea válida. – user1117774

0

¿Podemos ver la estructura de su mesa? Si estoy entendiendo esto, la suposición hecha por la consulta es que un registro puede ser solo meta_key - 'lat' o meta_key = 'long' no ambos porque cada fila solo tiene una columna meta_key y solo puede contener 1 valor correspondiente, no 2. Eso explicaría por qué no Obtenga resultados cuando conecta el con un AND; es imposible.

+0

Agregué una breve descripción de la estructura de la tabla en la primera publicación. Debería haber hecho eso antes, gracias por mencionarlo – user1117774

Cuestiones relacionadas