SELECT username, users.photo_url, fp, dp,users.vid,
GLength(LineStringFromWKB(LineString(AsBinary(PointFromText('POINT({$geolat} {$geolong})')),
AsBinary(location)))) AS distance
FROM users
INNER JOIN venues ON users.vid = venues.vid
LEFT JOIN deflects ON users.username = deflects.defender
WHERE username NOT LIKE '{$mysql['username']}'
AND username NOT LIKE '{$users['king']['username']}'
AND venues.location IS NOT NULL
HAVING
(distance <= (
SELECT MAX(distance) AS max_distance
FROM (
SELECT
GLength(LineStringFromWKB(LineString(AsBinary(PointFromText('POINT({$geolat} {$geolong})')),
AsBinary(location))))
AS distance
FROM users
INNER JOIN venues ON users.vid = venues.vid
LEFT JOIN deflects ON users.username = deflects.defender
WHERE users.fp = 0
AND username NOT LIKE '{$mysql['username']}'
AND username NOT LIKE '{$users['king']['username']}'
AND venues.location IS NOT NULL
AND deflects.dp IS NULL
ORDER BY distance LIMIT 5
) AS unfrozen)
OR vid = '{$vid}')
ORDER BY distance
现在我重复使用了很多相同的查询两次 - 特别是,我想避免不止一次地进行距离计算 - 但我无法弄清楚如何做到这一点。我正在使用MySQL,所以我不认为常见的表表达式是一种选择。另外,我遇到了临时表的麻烦。有没有办法用这种方式来表达这个查询,我可以重用距离计算?
另外,我知道我计算距离的方式与给定的geolat,geolong没有真正的距离,但它足够接近我的目的。
编辑: 而且......这就是我的工作,几乎完全基于理查德的回应:
SELECT username, distance, photo_url, vid, fp, dp
FROM (
SELECT username, photo_url, vid, fp, dp,
@d := distance AS distance,
@c := if(fp = 0
AND dp IS NULL
AND @d>=@max, @c+1, @c),
@max := if(fp = 0
AND dp IS NULL
AND @d>=@max
AND @c <= 5, @d, @max)
FROM (SELECT @max:=0, @d:=null, @c:=0) AS MaxTally
INNER JOIN (
SELECT username, photo_url, users.vid, users.fp, deflects.dp,
GLength(LineStringFromWKB(LineString(AsBinary(PointFromText('POINT({$geolat} {$geolong})')),
AsBinary(location))))
AS distance
FROM users
INNER JOIN venues ON users.vid = venues.vid
LEFT JOIN deflects ON users.username = deflects.defender
WHERE username NOT LIKE '{$mysql['username']}'
AND username NOT LIKE '{$users['king']['username']}'
AND venues.location IS NOT NULL
ORDER BY distance
) AllUsers
) AllUsersWithMaxTally
WHERE vid = '{$vid}' OR distance <= @max
ORDER BY distance
谢谢理查德!
答案 0 :(得分:2)
伪代码 - 如果需要,我会稍后修复代码,但这可能会让你开始自己找到答案。 MySQL允许你做疯狂的事情!
SELECT
username,
distance
FROM
(
SELECT
username,
@d:=distance AS distance,
@c := if(fp = 0
AND dp IS NULL
AND @d>=@max, @c+1, @c),
@max := if(fp = 0
AND dp IS NULL
AND @d>=@max
AND @c <= 5, @d, @max) MaxOf5Dist
FROM (select @max:=-1000, @d:=null, @c:=0) M
INNER JOIN (
SELECT
username, # others taken out for brevity
users.fp, deflects.dp,
GLength(LineStringFromWKB(LineString(AsBinary(
PointFromText('POINT({$geolat} {$geolong})')), AsBinary(location))))
AS distance
FROM users
CROSS JOIN venues ON users.vid = venues.vid
LEFT JOIN deflects ON users.username = deflects.defender
WHERE username NOT LIKE '{$mysql['username']}'
AND username NOT LIKE '{$users['king']['username']}'
AND venues.location IS NOT NULL
ORDER BY distance
) X
) Y
WHERE vid = '{$vid}' OR distance <= MaxOf5Dist
ORDER BY distance
答案 1 :(得分:0)