我想创建一些能够通过查询对距离最近的距离进行排名的东西。现在唯一的问题是我不确定如何为MySQL实现它。我想在Oracle中实现Rank分区之类的东西。现在这是我的问题:
SELECT p.idproduct,
p.common_name,
ROUND(
SQRT(
POW(69.1 * (s.store_lat - 4.946966), 2) +
POW(69.1 * (114.960770 - s.store_long) * COS(s.store_lat / 57.3), 2)),2) AS distance
FROM product p
INNER JOIN branches b
ON b.idproduct = p.idproduct
INNER JOIN store s
ON b.idstore = s.idstore
INNER JOIN
( SELECT DISTINCT p.common_name
FROM shopping_list_content s
INNER JOIN product p
ON s.iditem = p.idproduct
WHERE s.idlist =64
) s
ON s.common_name = p.common_name
现在它的结果如下:
idproduct | common_name | distance
1 | item 1 | 0
1 | item 1 | 1
2 | item 2 | 3
2 | item 2 | 1
3 | item 3 | 2
3 | item 3 | 0
并添加了我应该获得的排名:
idproduct | common_name | distance | rank
1 | item 1 | 0 | 1
1 | item 1 | 1 | 2
2 | item 2 | 3 | 2
2 | item 2 | 1 | 1
3 | item 3 | 2 | 2
3 | item 3 | 0 | 1
最后通过嵌套选择我会得到:
idproduct | common_name | distance | rank
1 | item 1 | 0 | 1
2 | item 2 | 1 | 1
3 | item 3 | 0 | 1
我在这里见过类似@curRank的内容(Rank function in MySQL),但不确定如何根据我当前的查询实现它。
我尝试使用GROUP BY作为common_name列,但我想这完全不是正确的方法。希望有人可以提供帮助。
答案 0 :(得分:0)
此查询在MySQL
中可以正常排名:
SELECT TAB1.idproduct,TAB1.common_name,TAB1.distance,
(TAB1.RN - TAB2.MN) + 1 RANK FROM
(SELECT T1.*,@ROWNUM := @ROWNUM + 1 RN FROM
(SELECT * FROM (SELECT p.idproduct,
p.common_name,
ROUND(
SQRT(
POW(69.1 * (s.store_lat - 4.946966), 2) +
POW(69.1 * (114.960770 - s.store_long) * COS(s.store_lat / 57.3), 2)),2) AS distance
FROM product p
INNER JOIN branches b
ON b.idproduct = p.idproduct
INNER JOIN store s
ON b.idstore = s.idstore
INNER JOIN
( SELECT DISTINCT p.common_name
FROM shopping_list_content s
INNER JOIN product p
ON s.iditem = p.idproduct
WHERE s.idlist =64
) s
ON s.common_name = p.common_name)TABLE1
ORDER BY idproduct,common_name,distance)T1,
(SELECT @ROWNUM := 0) RN)TAB1
INNER JOIN
(SELECT T2.*,MIN(RN) MN FROM
(SELECT T1.*,@ROWNUM := @ROWNUM + 1 RN FROM
(SELECT * FROM (SELECT p.idproduct,
p.common_name,
ROUND(
SQRT(
POW(69.1 * (s.store_lat - 4.946966), 2) +
POW(69.1 * (114.960770 - s.store_long) * COS(s.store_lat / 57.3), 2)),2) AS distance
FROM product p
INNER JOIN branches b
ON b.idproduct = p.idproduct
INNER JOIN store s
ON b.idstore = s.idstore
INNER JOIN
( SELECT DISTINCT p.common_name
FROM shopping_list_content s
INNER JOIN product p
ON s.iditem = p.idproduct
WHERE s.idlist =64
) s
ON s.common_name = p.common_name)TABLE1
ORDER BY idproduct,common_name,distance)T1,
(SELECT @ROWNUM := 0) RN)T2
GROUP BY idproduct,common_name)TAB2
ON TAB1.idproduct = TAB2.idproduct AND
TAB1.common_name = TAB2.common_name;
答案 1 :(得分:0)
这是一个解决方案,可以在您的描述中实现最终结果集:
SELECT a.idproduct, a.common_name, a.distance FROM
(
SELECT (@rownumber1:= @rownumber1 + 1) AS rn, dt.*
FROM distance_table dt,(SELECT @rownumber1:= 0) nums
ORDER BY common_name, distance
) a
JOIN
(
SELECT MIN(rn) AS minRn, common_name FROM
(
SELECT (@rownumber:= @rownumber + 1) AS rn, dt.*
FROM distance_table dt,(SELECT @rownumber:= 0) nums
ORDER BY common_name, distance
) c
GROUP BY common_name
) b
ON a.common_name = b.common_name
AND a.rn = b.minRn
以下是SQL Fiddle
的代码我假设已经计算了距离表,所以在上面的查询中,只要提到distance_table
,就可以用查询替换它,它将距离结果集作为输出。
以下是每个组中排名的查询:
SELECT a.idproduct, a.common_name, a.distance, (a.rn - b.minRn + 1) AS rank FROM
(
SELECT (@rownumber1:= @rownumber1 + 1) AS rn, dt.*
FROM distance_table dt,(SELECT @rownumber1:= 0) nums
ORDER BY common_name, distance
) a
JOIN
(
SELECT MIN(rn) AS minRn, common_name FROM
(
SELECT (@rownumber:= @rownumber + 1) AS rn, dt.*
FROM distance_table dt,(SELECT @rownumber:= 0) nums
ORDER BY common_name, distance
) c
GROUP BY common_name
) b
ON a.common_name = b.common_name
以下是SQL Fiddle的代码 如果它能解决您的问题,请告诉我。