我有一张表格显示城市之间的距离,如:
CREATE TABLE `distances` (
`city1` int(10) unsigned NOT NULL,
`city2` int(10) unsigned NOT NULL,
`distance` double(12,4) DEFAULT NULL);
我需要的是一个查询,显示距离给定城市不超过20公里的所有城市(比如说键#34; 1")。我想要最多10个城市,所以到目前为止这似乎很容易:
SELECT city2, distance FROM distances WHERE
city1='1'
AND distance <= 20
ORDER BY distance ASC
LIMIT 10;
但是:我想要显示至少3个城市,这意味着如果在半径20公里范围内只有1个城市,我需要添加2个城市,距离给定城市的距离超过20公里(最好按距离ASC排序为好吧),像:
Result:
city key 7: 18 km
city key 24: 22 km
city key 4: 23 km
如何将此添加到我的查询中?
答案 0 :(得分:3)
如果您只想在一个查询中完成所有操作,您应该能够执行以下操作。我们的想法是,如果第三个位置后的答案都在20英里/公里范围内,那么您只能列出3个以上的答案。
SET @index=0;
SELECT @index:=@index+1 AS `index`
, t.city2
, t.distance
FROM (SELECT * from distances ORDER BY distance LIMIT 10) t
WHERE t.city1='1'
AND (t.distance <= 20 OR @index <= 3)
编辑:感谢notulysses改进了性能和风格。感谢戈登实际上发现它不起作用;)
答案 1 :(得分:0)
如果您愿意,可以在没有变量的情况下执行此操作。以下内容需要重复删除,但在13条记录中,这是最小的努力:
select *
from ((select d.*
from distances d
where city = '1'
order by distance
limit 3
) union
(select d.*
from distances d
where distance <= 20 and city = '1'
order by distance
limit 10
)
) d
order by distance
limit 10;
删除重复项是不优雅的,因此以下功能可以执行您的操作而无需重复删除:
(select d.*
from distances d
where city = '1'
order by distance
limit 3
) union all
(select d.*
from distances d
where distance <= 20 and city = '1'
order by distance
limit 3, 7
)
第二个子查询使用offset
。如果第三个距离大于20,则第二个部分不返回任何内容。否则,如果第三个距离较小,则忽略前三个记录。