簡體   English   中英

MySQL中的計數或條件限制

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM