簡體   English   中英

如何 select 區分一列但使用 acos-cos-radians 公式返回所有列

[英]How to select distinct one column but return all columns with acos-cos-radians formula

我想獲取一個名為 supplier_products 的表,其中包含以下列

ID Item_id supplier_id variant_id  price    lat        lng   serving_radius(in km)

1     1      2            12       22.00  26.11360000 85.39430000    1
2     1      3            12       44.00  26.11360000 85.39430000    4
3     1      2            13       25.00  26.11360000 85.39430000    4
4     1      3            13       23.00  26.11360000 85.39430000    4

現在搜索緯度和經度附近的供應商產品說($lat = 26.1136;$long = 85.3643;) 我正在使用這個查詢

SELECT *, (6371 * acos(cos(radians('$lat')) * cos(radians(lat)) * cos( radians(lng) - radians('$long')) + sin(radians('$lat')) * sin(radians(lat)))) AS distance FROM supplier_products HAVING distance <= serving_radius ORDER BY distance")

上面的查詢返回服務於輸入$lat & $long的所有行。

但現在我想只返回那些具有不同 variant_id 的行的所有列,這些行服務於輸入$lat & $long

我嘗試使用GROUP BY -

SELECT *, (6371 * acos(cos(radians('$lat')) * cos(radians(lat)) * cos( radians(lng) - radians('$long')) + sin(radians('$lat')) * sin(radians(lat)))) AS distance FROM supplier_products GROUP BY variant_id HAVING distance <= serving_radius")

但它消除了一些所需的行,因為GROUP BYHAVING子句之前執行。 因此,它消除了服務半徑內的一些必需行。

我正在使用PHPMYSQL

編輯-我想要這個作為我的 output

ID Item_id supplier_id variant_id  price    lat        lng   serving_radius(in km)

2     1      3            12       44.00  26.11360000 85.39430000    4
3     1      2            13       25.00  26.11360000 85.39430000    4

由於ID-1的行不服務於輸入$lat/$long

但是我的嘗試給出了以下結果-

ID Item_id supplier_id variant_id  price    lat        lng   serving_radius(in km)

3     1      2            13       25.00  26.11360000 85.39430000    4

因為GROUP BY消除了2nd row

如果您想要可預測的結果,您的要求仍然不完整。 你要求從幾行中只選擇一行。 為什么您想要的結果顯示 id=3 而不是 id=4? 我猜你隨機選擇了兩者之一。

這個查詢( https://www.db-fiddle.com/f/USMrhc8gLcRD2rAmuzYzH/0 )為你做。

SET @lat := 26.120888;
SET @long := 85.364832;
SELECT ANY_VALUE(supplier_id), variant_id, ANY_VALUE(price)  
FROM  ( SELECT ID,
               (6371 * acos(cos(radians(@lat)) * cos(radians(lat)) *
                cos( radians(lng) - radians(@long)) + sin(radians(@lat)) * 
                sin(radians(lat)))) AS distance
          FROM supplier_products 
     ) t WHERE distance < serving_radius
GROUP BY variant_id

它有一個子查詢來顯示表的變體,該變體顯示與提供的@lat 和@long 值的距離。 它顯示 ID 和距離。 就是這個。 https://www.db-fiddle.com/f/guagWYVXXaf7cPkbojj9KD/2

        SELECT *, 
               (6371 * acos(cos(radians(@lat)) * cos(radians(lat)) *
                cos( radians(lng) - radians(@long)) + sin(radians(@lat)) * 
                sin(radians(lat)))) AS distance
          FROM supplier_products 

然后它在帶有 GROUP BY 的外部查詢中使用該子查詢,見上文。

但是,因為您希望每個變體只需要一行,並且您沒有告訴我們如何在有多行時選擇該行,所以查詢使用ANY_VALUE() function為結果中的每一列選擇一個可用值。

早於 8.0 的 MySQL 版本不需要 ANY_VALUE() 函數,因為 MySQL 臭名昭著的非標准 GROUP BY 處理: 請閱讀此內容。

當心:如果你讓 MySQL 使用這個 ANY_VALUE() 東西,無論是隱式還是顯式,你都會讓你的測試人員和你的用戶發瘋。 他們今天有時會得到與上周不同的結果,他們會想知道自己做錯了什么。 請不要這樣做。

還有一件事:您的距離公式因在非常小的距離上拋出異常而臭名昭著。 通過像這樣修改它以使用 LEAST(),確保它永遠不會嘗試使用值大於 1 的 ACOS()。 https://www.db-fiddle.com/f/USMrhc8gLcRD2rAmuzYzH/1

    (6371 * acos(LEAST(1.0,cos(radians(@lat)) * cos(radians(lat)) *
    cos( radians(lng) - radians(@long)) + sin(radians(@lat)) *
    sin(radians(lat)))))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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