[英]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 BY
在HAVING
子句之前執行。 因此,它消除了服務半徑內的一些必需行。
我正在使用PHP
和MYSQL
編輯-我想要這個作為我的 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.