[英]MySQL - Order by in Inner query. What am I missing?
我有以下表格和關系:
Players:
foreign_key to User
Users:
foreign_key to City
Cities:
latitude (float)
longitude (float)
我試圖讓所有與用戶相關的教授來自某個城市或近城。
我有這個查詢,它給出了具有特定緯度和經度以及給定城市緯度和經度的距離的near_by(20km)城市。 在這種情況下, latitude = 41.353312 and longitude = 1.976252
:
SELECT cities.*,
6371 *
acos(cos(radians(41.353312)) *
cos(radians(cities.latitude)) *
cos(radians(cities.longitude) - radians(1.976252)) +
sin(radians(41.353312))*sin(radians(cities.latitude)))
AS km_away FROM `cities` GROUP BY km_away ASC HAVING km_away <= 20
我已經嘗試了這個查詢( 這不起作用 ),我希望它能讓我返回給定城市(緯度和經度)附近的相關用戶城市的玩家。
SELECT COUNT(*)
FROM `players`
INNER JOIN `users`
ON `users`.`id` = `players`.`user_id`
INNER JOIN `cities`
ON `cities`.`id` = `users`.`city_id`
WHERE
(
cities.id IN
(SELECT cities.*,
6371 *
acos(cos(radians(41.353312)) *
cos(radians(cities.latitude)) *
cos(radians(cities.longitude) - radians(1.976252)) +
sin(radians(41.353312))*sin(radians(cities.latitude))) AS km_away
FROM `cities`
GROUP BY km_away ASC
HAVING km_away <= 20)
)
我也想要:
1 - 按照相關用戶城市到指定城市的距離排序玩家。
2 - 獲取返回的每條記錄的距離(值)。
我不清楚你想要返回什么樣的結果集。 但是看看你的問題,我想你想要你的子查詢(+1!用於距離巴塞羅那的“大圓距”計算距離!)作為行源。
一種方法是將子查詢用作“內聯視圖”,而不是在WHERE子句中引用它。
由於該查詢返回cities表中的所有列,因此它基本上可以替換查詢中的cities表。
不需要GROUP BY子句。 當兩個城市與給定的緯度/經度等距時,它僅用於消除結果集中的行。 (我不相信這是你想要的行為,想要這樣做並沒有錯,但這很不尋常。)
SELECT COUNT(*)
FROM `players`
INNER JOIN `users`
ON `users`.`id` = `players`.`user_id`
INNER JOIN
(SELECT cities.*,
6371 *
acos(cos(radians(41.353312)) *
cos(radians(cities.latitude)) *
cos(radians(cities.longitude) - radians(1.976252)) +
sin(radians(41.353312))*sin(radians(cities.latitude))) AS km_away
FROM `cities`
HAVING km_away <= 20
ORDER BY km_away
) `cd`
ON `cd`.`id` = `users`.`city_id`
注意:我給了內聯視圖cd
的別名(我讀作城市距離的簡寫。
COUNT聚合將僅返回一行,因此不需要ORDER BY。 如果更改SELECT列表,並希望按特定順序返回行,請在最外面的查詢中添加ORDER BY,例如
ORDER BY cd.km_away ASC
更新:
您應該能夠引用cities
, players
, users
表中的任何列以及SELECT列表中的計算距離( km_away
)。 當然,您可以指定要返回的列,而不是使用“。*”。 但是`cd.km_away'可以在外部查詢中引用(SELECT列表,WHERE子句,ORDER BY等)
SELECT cd.km_away
, cd.*
, players.*
, users.*
FROM `players`
INNER JOIN `users`
ON `users`.`id` = `players`.`user_id`
INNER JOIN
(SELECT cities.*,
6371 *
acos(cos(radians(41.353312)) *
cos(radians(cities.latitude)) *
cos(radians(cities.longitude) - radians(1.976252)) +
sin(radians(41.353312))*sin(radians(cities.latitude))) AS km_away
FROM `cities`
HAVING km_away <= 20
ORDER BY km_away
) `cd`
ON `cd`.`id` = `users`.`city_id`
ORDER BY cd.km_away
你有一個GROUP BY子句的ASC。 你的意思是使用ORDER BY。
編輯請原諒我對mysql的無知。 我更喜歡堅持使用標准方法,特別是當它們也是最簡單的方法時。 OP在粗體文本中注明“哪些不起作用”,在閱讀整個問題之前,我認為我的答案原來答案可能就是問題所在。
SELECT
6371 *
acos(cos(radians(41.353312)) *
cos(radians(cities.latitude)) *
cos(radians(cities.longitude) - radians(1.976252)) +
sin(radians(41.353312))*sin(radians(cities.latitude))) as km,
...
FROM
players
INNER JOIN users ON users.id = players. user_id
INNER JOIN cities ON cities.id = users.city_id
WHERE
6371 *
acos(cos(radians(41.353312)) *
cos(radians(cities.latitude)) *
cos(radians(cities.longitude) - radians(1.976252)) +
sin(radians(41.353312))*sin(radians(cities.latitude)))
<= 20
ORDER BY
6371 *
acos(cos(radians(41.353312)) *
cos(radians(cities.latitude)) *
cos(radians(cities.longitude) - radians(1.976252)) +
sin(radians(41.353312))*sin(radians(cities.latitude)))
ASC
派生表/虛擬表/內聯視圖會將其清理一下。
SELECT cities.km, ...
FROM
players
INNER JOIN users ON users.id = players. user_id
INNER JOIN
(
SELECT
cities.*, /* don't know if this works on mysql */
6371 *
acos(cos(radians(41.353312)) *
cos(radians(cities.latitude)) *
cos(radians(cities.longitude) - radians(1.976252)) +
sin(radians(41.353312))*sin(radians(cities.latitude))) as km
) as cities /* maybe another name is appropriate */
ON cities.id = users.city_id
WHERE cities.km <= 20
ORDER BY cities.km ASC
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.