带有多个where语句的sql查询

时间:2011-12-27 14:34:23

标签: mysql

我有一个相当的,对我来说,复杂的mysql查询,我完全陷入困境,无法在网上找到任何答案。

这是我的疑问:

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

当然我只用1个语句测试了查询,并且工作正常。因此,如果我只传递长或纬度部分,那么我得到结果。只有当我尝试将它们拼接在一起时才会得到不同的结果。

提前感谢您的帮助!

表结构如下:

表项目: ID 项目名称 ITEM_DESCRIPTION

表元: meta_id ITEM_ID meta_key meta_value

解决方案

对于任何有兴趣的人,我终于设法解决了这个问题。谢谢大家的帮助和内心。

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

4 个答案:

答案 0 :(得分:30)

在评估GROUP BY子句条件后,您需要考虑WHERE。并且WHERE子句始终只考虑一行,这意味着在您的查询中,meta_key条件将始终阻止选择任何记录,因为一列不能有一行的多个值< /强>

那么多余的meta_value检查呢?如果允许值既小又大于给定值,那么它的实际值根本不重要 - 可以省略检查。

根据您的一条评论,您要检查距离指定位置不到一定距离的地方。为了获得正确的距离,您实际上必须使用某种适当的距离函数(例如,请参阅this question)。但是这个SQL应该让你知道如何开始:

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

答案 1 :(得分:6)

此..

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

相同
(
        (meta_key = 'lat')
)

将它们全部加在一起(同样适用于long过滤器)你有这个不可能的WHERE子句,它不会产生任何行,因为meta_key不能是一行中的2个值

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

您需要检查您的操作员以确保获得正确的逻辑

答案 2 :(得分:3)

什么是meta_key?删除所有meta_value条件,减少,最后你得到这个:

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

由于meta_key永远不能同时等于两个不同的值,因此不会返回任何结果。


基于此问题和答案中的评论到目前为止,听起来您正在寻找更多内容:

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

请注意顶级条件之间的OR。这是因为您需要lat long的记录,因为任何单个记录都不会是lat {{1 }}

我仍然不确定你要通过内部条件来完成什么。 任何非空值都将匹配这些数字。所以也许你可以详细说明你想在那里做什么。我也不确定long子句的用途,但这可能完全超出了这个问题的范围。

答案 3 :(得分:1)

我们能看到你桌子的结构吗?如果我理解这一点,那么查询的假设是记录只能是meta_key - 'lat'meta_key = 'long',因为每行只有一个meta_key列,并且只能包含1个相应的值,而不是2.这可以解释为什么在连接AND时没有得到结果;不可能。