[英]Limit by count OR condition in MySQL
我正在制作一個使用地理位置的網絡應用程序,我正在掀起一個“附近的地方”視圖。 這是非常簡單的邏輯:它顯示了存儲在數據庫中的最近5個位置。 完善。
訣竅是我希望它返回最近的5個地方或兩英里內的所有地方,以較大者為准。 換句話說,我希望用戶能夠至少看到兩英里內的所有地方,但如果該半徑內沒有5個地方,我希望他們顯示最接近的5個。
讓我們將它們用於樣本數據集。 第1組:
| id | name | distance |
+----+----------------------+-----------+
| 3 | Earl of Sandwich | 0.3 |
| 4 | Nails 'n More | 0.8 |
| 22 | City Hotel | 1.7 |
| 5 | Mighty Medicine | 2.1 |
| 25 | Wonder Wings | 2.5 |
| 6 | Jean Warehouse | 2.7 |
| 9 | Ship Safe & Speedy | 2.9 |
| 2 | Bagel Bonus | 4.1 |
+----+----------------------+-----------+
第2集:
| id | name | distance |
+----+----------------------+-----------+
| 3 | Earl of Sandwich | 0.1 |
| 4 | Nails 'n More | 0.2 |
| 5 | Mighty Medicine | 0.5 |
| 6 | Jean Warehouse | 0.7 |
| 9 | Ship Safe & Speedy | 0.9 |
| 2 | Bagel Bonus | 1.2 |
| 22 | City Hotel | 1.7 |
| 25 | Wonder Wings | 2.1 |
+----+----------------------+-----------+
在第一組中,我想要返回第3,4,25,5和25行。在第二組中,我想要顯示3,4,5,6,9,2和22。
我知道我總是可以將查詢限制在100個位置,並通過PHP中的結果集進行過濾...但我想知道是否有更有效的方法在SQL中正確執行。
總之,執行此操作的方法是運行兩個查詢並獲取集合的UNION。 而已。 這樣做的確很少有性能損失,因為如果結果中確實有超過5行,則已經需要第一組(可以產生> 5行)。
為了說明,我只使用同一樣本表中的2列,而不是使用2個數據集,查詢將在下面進一步顯示:
drop table if exists tbl1;
create table tbl1 (
id int,
name varchar(100),
distance1 float,
distance2 float
);
insert tbl1 values
( 3 , 'Earl of Sandwich ', 0.3, 0.1),
( 4 , 'Nails ''n More ', 0.8, 0.2),
( 22 , 'City Hotel ', 1.7, 1.7),
( 5 , 'Mighty Medicine ', 2.1, 0.5),
( 25 , 'Wonder Wings ', 2.5, 2.1),
( 6 , 'Jean Warehouse ', 2.7, 0.7),
( 9 , 'Ship Safe & Speedy ', 2.9, 0.9),
( 2 , 'Bagel Bonus ', 4.1, 1.2);
以及查詢和結果:
/* query 1 */
select id, name, distance1
from (
select *
from tbl1
where distance1 <= 2.0
order by distance1) a
union
select id, name, distance1
from (
select *
from tbl1
order by distance1
limit 5) b;
/* result 1 */
id;name;distance1
3;Earl of Sandwich ;0.3
4;Nails 'n More ;0.8
22;City Hotel ;1.7
5;Mighty Medicine ;2.1
25;Wonder Wings ;2.5
/* query 2 */
select id, name, distance2
from (
select *
from tbl1
where distance2 <= 2.0
order by distance2) a
union
select id, name, distance2
from (
select *
from tbl1
order by distance2
limit 5) b;
/* result 2 */
id;name;distance2
3;Earl of Sandwich ;0.1
4;Nails 'n More ;0.2
5;Mighty Medicine ;0.5
6;Jean Warehouse ;0.7
9;Ship Safe & Speedy ;0.9
2;Bagel Bonus ;1.2
22;City Hotel ;1.7
這個查詢的性能和它一樣好。
第一個UNION部分挑出了<2km的部分。 這是必要的,因為你想要所有的比賽。
下一部分選擇前5名並假設你有一個索引,這是很容易收集的。 兩個部分的組合(UNION)非常快。
如果是我,我會讓您的查詢返回按距離排序的所有位置。 然后在PHP中你可以跳到陣列中的第5位(這將是距離第5個最遠的地方,因為你已經按距離訂購了查詢)並檢查它是否在2英里內。 如果它然后返回前5個,如果沒有則返回所有它們。
所以你的查詢就是:
SELECT id, name, distance FROM places ORDER BY distance ASC
SELECT * FROM places ORDER BY distance ASC LIMIT 5
不管怎樣,最近的地方都會先拉(按asc排序),所以沒關系。
LIMIT是從數據庫中提取的最大結果,因此用戶獲得的最大位置是5,可能更少但不是更多。
你可以肯定使用mysql限制(並鼓勵)訂單:
SELECT * FROM `table` ORDER BY `distance` ASC LIMIT 5;
“ASC”告訴查詢以遞增的方式(從最小到最高)對行進行排序。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.