1

DB に、id、name、country_id、lat(緯度)、lng(経度) を持つ、cities というテーブルがあります。私のアプリケーションでは、ユーザーの場所を取得してから、ユーザーの場所に最も近い都市を見つけようとするので、最初は次のようにしました。

select * , ( sqrt( pow(lat - 31.205 , 2) + pow(lng - 29.907 , 2) ) ) as min_dis from cities

次のような結果が返されました。

+----+------------------+------------+---------------+---------------+----------------------+
| id | name             | country_id | lat           | lng           | min_dis              |
+----+------------------+------------+---------------+---------------+----------------------+
|  1 | Cairo            |         61 | 30.0444196000 | 31.2357116000 |   1.7642055948326205 |
|  2 | Alexandria       |         61 | 31.2000924000 | 29.9187387000 | 0.012723270627083274 |
|  3 | Tanta            |         61 | 30.7865086000 | 31.0003757000 |   1.1707286078440424 |
|  7 | North Coast      |         61 | 28.0488161000 | 34.4371483000 |    5.521208240105792 |
|  8 | Marsa Matruh     |         61 | 31.3543445000 | 27.2373159000 |    2.673858069059212 |
|  9 | Hurghada         |         61 | 27.2578957000 | 33.8116067000 |    5.552079415567052 |
| 10 | Ismailia         |         61 | 30.5964923000 | 32.2714587000 |   2.4415049795085366 |
| 11 | Ain ElSokhna     |         61 | 29.5927778000 | 32.3416667000 |    2.920079170546876 |
| 12 | El Mansoura      |         61 | 31.0409483000 | 31.3784704000 |    1.480587078948432 |
+----+------------------+------------+---------------+---------------+----------------------+

結果でわかるように、ID=2 の "Alexandria" 市がユーザーの場所に最も近い都市です。

そして、私がこのようなことをしようとすると:

select MIN( sqrt( pow(lat - 31.205 , 2) + pow(lng - 29.907 , 2) ) ) as min_dis from cities;

私はこれを得る:

+----------------------+
| min_dis              |
+----------------------+
| 0.012723270627083274 |
+----------------------+

これは私には理にかなっています...しかし、これを試してみると:

select * , MIN( sqrt( pow(lat - 31.205 , 2) + pow(lng - 29.907 , 2) ) ) as min_dis from cities;

私はこれを得る:

+----+-------+------------+---------------+---------------+----------------------+
| id | name  | country_id | lat           | lng           | min_dis              |
+----+-------+------------+---------------+---------------+----------------------+
|  1 | Cairo |         61 | 30.0444196000 | 31.2357116000 | 0.012723270627083274 |
+----+-------+------------+---------------+---------------+----------------------+

返された min_dis は正しいですが、都市データは正しくありません!! 「アレクサンドリア」のレコードを返すべきだと思ったのですが、そうではありませんでした..理由を知っている人はいますか??

編集: このクエリは私のために働いた:

SELECT `cities`.* FROM `cities` WHERE ((sqrt(pow(lat - 31.205 , 2) + pow(lng - 29.907 , 2)))= (SELECT MIN((sqrt(pow(lat - 31.205 , 2) + pow(lng - 29.907 , 2)))) AS min_id FROM `cities` ))

そして返されました:

+----+------------+------------+---------------+---------------+
| id | name       | country_id | lat           | lng           |
+----+------------+------------+---------------+---------------+
|  2 | Alexandria |         61 | 31.2000924000 | 29.9187387000 |
+----+------------+------------+---------------+---------------+

私が欲しいのは、なぜこのクエリが機能しなかったのかを理解することだけですか?

select * , MIN( sqrt( pow(lat - 31.205 , 2) + pow(lng - 29.907 , 2) ) ) as min_dis from cities;
4

2 に答える 2

2

これを試して:

select * , ( sqrt( pow(lat - 30.4990 , 2) + pow(lng - 29.4435 , 2) ) ) 
                                                    as min_dis 
from cities 
order by sqrt( pow(lat - 30.4990 , 2) + pow(lng - 29.4435 , 2) ) 
limit 1

結果を取得するには、最初のクエリで order by を実行するだけです

于 2012-08-02T09:21:09.477 に答える
1

集計関数を使用する場合、非集計フィールドをGROUP BYステートメントで正しく指定する必要があります。そうしないと、結果が未指定になり、通常は集計照合で使用される最初または最後のレコードになります。

MIN(...)テーブルから最小値を返すという意味ではなく、先頭のフィールドとGROUP BYステートメントによって指定された現在のグループの最小値を意味します。テーブル全体の最小値が必要な場合は、他のレコードを使用して、 Joe G JosephORDER BYが上で行ったように an を使用して最小のレコードを取得するか、または行ったように実行して、取得するサブクエリと一致するように指示する必要がありますグループ化フィールドがないため、テーブル全体のMIN(...)

于 2012-08-02T10:06:35.037 に答える