我有一个相当的,对我来说,复杂的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
答案 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
时没有得到结果;不可能。