基于MySQL中具有相同行值的特定列对列进行排序

基于MySQL中具有相同行值的特定列对列进行排序,mysql,sql,ranking,Mysql,Sql,Ranking,我想通过一个查询创建一个能够对距离用户最近的距离进行排名的东西。现在唯一的问题是我不确定如何为MySQL实现它。我正在考虑类似于Oracle中实现的等级划分。现在我的问题是: 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

我想通过一个查询创建一个能够对距离用户最近的距离进行排名的东西。现在唯一的问题是我不确定如何为MySQL实现它。我正在考虑类似于Oracle中实现的等级划分。现在我的问题是:

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()的内容,但不确定如何基于当前查询实现它


我试着在common_name列中使用groupby,但我想这完全不是正确的方法。希望有人能提供帮助。

此查询在
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
这是你的密码

我假设已经计算了距离表,所以在上面的查询中,只要提到
distance\u 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
这是你的密码
让我知道它是否解决了您的问题。

所以我认为您已经完成了距离计算,对吗?现在,您想在基于距离的项目组中获得排名吗?让我知道我的解释是否正确是的,距离已经计算好了。我只需要根据最近的距离对它进行排名。这是可行的,但在距离的排名上有点奇怪。一个距离是0、22.09和3.20,但结果是2,1,3,这是不正确的。大多数情况下发生的情况是距离为0。