您可以使用自联接获取此信息:
SELECT
table.id,
bid_user_lat.meta_value,
bid_user_lng.meta_value
FROM
table
JOIN
table bid_user_lat
ON table.id = bid_user_lat.id
AND table.meta_key = "bid_user_lat"
JOIN
table bid_user_lng
ON table.id = bid_user_lng.id
AND table.meta_key = "bid_user_lng"
WHERE
{ distance clause }
...距离条款是您确保它在适当距离内的地方。您可以bid_user_lat.meta_value
用作bid_user_lat
值,也可以bid_user_lng.meta_value
用作bid_user_lng
计算中的值。
如果您想在与 Shop 结果相同的查询中返回 User 结果,那么您可以执行与上述查询相同的查询(当然使用 Shops 而不是 Users),并使用UNION
or连接它们UNION ALL
。
边注:
如果您对数据库有任何控制权,您可能需要重新访问该设计。上面的解决方案无论如何都不理想......如果一个用户总是有一个bid_user_lat和一个bid_user_lng字段,或者即使它只是用户的一个公共属性,那么它真的应该在用户表中有自己的列。
更正:
我JOIN
ing 不正确。该ON
子句应使用bid_user_lng.meta_key = "bid_user_lat"
而不是wp_usermeta.meta_key = "bid_user_lat"
. 您还需要添加一个GROUP BY
子句,这样您就不会有重复的记录。将这些应用于上面的查询,您将获得:
SET @lat = '48.453541';
SET @lng = '-123.491765';
SET @radius = '10000';
SELECT
wp_usermeta.user_id,
bid_user_lat.meta_value,
bid_user_lng.meta_value,
( 3959 * acos( cos( radians( @lat ) ) * cos( radians( bid_user_lat.meta_value ) ) * cos( radians( bid_user_lng.meta_value ) - radians( @lng ) ) + sin( radians( @lat ) ) * sin( radians( bid_user_lat.meta_value ) ) ) ) AS distance
FROM
wp_usermeta
JOIN
wp_usermeta bid_user_lat
ON wp_usermeta.user_id = bid_user_lat.user_id
AND bid_user_lat.meta_key = "bid_user_lat"
JOIN
wp_usermeta bid_user_lng
ON wp_usermeta.user_id = bid_user_lng.user_id
AND bid_user_lng.meta_key = "bid_user_lng"
GROUP BY wp_usermeta.user_id
HAVING distance < @radius ORDER BY distance LIMIT 0 , 20;
这是它有效的确认:
mysql> CREATE TABLE wp_usermeta (user_id INTEGER UNSIGNED, meta_key VARCHAR(255), meta_value VARCHAR(255));
Query OK, 0 rows affected (0.25 sec)
mysql> INSERT INTO wp_usermeta (user_id, meta_key, meta_value)
-> VALUES
-> (1, "bid_user_lat", "45.000"), (1, "bid_user_lng", "-150.000"),
-> (2, "bid_user_lat", "20.000"), (2, "bid_user_lng", "20.000"),
-> (3, "bid_user_lat", "-300.000"), (3, "bid_user_lng", "70.000");
Query OK, 6 rows affected (0.16 sec)
Records: 6 Duplicates: 0 Warnings: 0
mysql> SELECT
-> wp_usermeta.user_id,
-> bid_user_lat.meta_value,
-> bid_user_lng.meta_value,
->
-> ( 3959 * acos( cos( radians( @lat ) ) * cos( radians( bid_user_lat.meta_value ) ) * cos( radians( bid_user_lng.meta_value ) - radians( @lng ) ) + sin( radians( @lat ) ) * sin( radians( bid_user_lat.meta_value ) ) ) ) AS distance
->
-> FROM
-> wp_usermeta
-> JOIN
-> wp_usermeta bid_user_lat
-> ON wp_usermeta.user_id = bid_user_lat.user_id
-> AND bid_user_lat.meta_key = "bid_user_lat"
-> JOIN
-> wp_usermeta bid_user_lng
-> ON wp_usermeta.user_id = bid_user_lng.user_id
-> AND bid_user_lng.meta_key = "bid_user_lng"
->
-> GROUP BY wp_usermeta.user_id
->
-> HAVING distance < @radius ORDER BY distance LIMIT 0 , 20;
+---------+------------+------------+--------------------+
| user_id | meta_value | meta_value | distance |
+---------+------------+------------+--------------------+
| 1 | 45.000 | -150.000 | 1271.3329043047352 |
| 3 | -300.000 | 70.000 | 4905.4310014631055 |
| 2 | 20.000 | 20.000 | 7198.549954690863 |
+---------+------------+------------+--------------------+
3 rows in set (0.05 sec)