[英]Rank column based on a specific column with same row values for MySQL
我想创建一些东西来对通过查询最接近用户的距离进行排名。 现在唯一的问题是我不确定如何为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之类的东西( MySQL中的Rank函数 ),但是不确定如何根据当前查询实现它。
我尝试将GROUP BY用于common_name列,但我想这绝对不是正确的方法。 希望有人能帮忙。
该查询在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;
这是在您的描述中获得最终结果集的解决方案:
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的代码让我知道它是否解决了您的问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.