簡體   English   中英

MySQL - 在內部查詢中排序。 我錯過了什么?

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

更新:

您應該能夠引用citiesplayersusers表中的任何列以及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.

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