【问题标题】:How to create a MySQL 5.6 Rank with JOIN and multiple sorting criteria如何使用 JOIN 和多个排序条件创建 MySQL 5.6 Rank
【发布时间】:2020-07-13 08:12:56
【问题描述】:

我一直在尝试返回 SQL 查询的排名。

SELECT c.id, c.score, i.sheetscore, @curRank := @curRank + 1 AS rank
FROM chart c LEFT JOIN indicator as i
ON c.indicator_id = i.id, (
SELECT @curRank :=0
) q
ORDER BY c.score DESC, i.sheetscore DESC
;

最后一行应显示正确显示的排序排名。我应该看到 Rank = 1,2,3 但我得到了这个...我已经尝试了 SQL 语句的多种变体,但我无法找到解决方案。

'ID','SCORE','SHEETSCORE', 'RANK'
'11767', '1', '0.7325', '11767'
'11765', '1', '0.7325', '11765'
'8365', '1', '0.6925', '8365'
'8363', '1', '0.6925', '8363'
'8615', '1', '0.6875', '8615'
'8617', '1', '0.6875', '8617'
'11646', '1', '0.685455', '11646'
'11647', '1', '0.685455', '11647'

理想情况下,我会使用此查询:

SELECT RANK from Chart where ID= 11646  ## as an example

【问题讨论】:

  • 考虑升级到 MySQL 8+。
  • @TimBiegeleisen - 我受到 Windows Dev 设置的限制......而且我的提供商仍然只支持 5.7.23

标签: mysql sql ranking


【解决方案1】:

我建议先在子查询中加入和排序,然后再计算排名。此外,您不应该混合使用隐式和显式连接 - 事实上,始终使用显式连接:

SELECT x.*, @curRank := @curRank + 1 AS rank
FROM (
    SELECT c.id, c.score, i.sheetscore
    FROM chart c 
    LEFT JOIN indicator i ON c.indicator_id = i.id
    ORDER BY c.score DESC, i.sheetscore DESC
) x
CROSS JOIN (SELECT @curRank :=0) q
ORDER BY score DESC, sheetscore DESC

请注意,如果您运行的是 MySQL 8.0,则直接使用 row_number()

SELECT 
    c.id, 
    c.score, 
    i.sheetscore, 
    ROW_NUMBER() OVER(ORDER BY c.score DESC, i.sheetscore DESC) rn
FROM chart c 
LEFT JOIN indicator i ON c.indicator_id = i.id
ORDER BY c.score DESC, i.sheetscore DESC

【讨论】:

  • 你将如何使用这个脚本来完成问题的第二部分? select * from <<this script>> where c.id = 8615 例如?当我在最后一个 ORDER BY 之前添加 WHERE 时,我总是会得到 rank = 1
【解决方案2】:

另一种选择:

确定一个或两个项目的一种非常低效的方法,但对于那些使用 PANDAS 和 Python 并且有许多类似查询的人来说,一个很好的解决方案是将您的 SQL 查询下载到 Dataframe,然后使用 Pandas 的排名和查询工具 - 分两步:

第 1 步 - 从上面运行 @GMB 的答案:

conn = pymysql.connect(host='localhost',
                       database='db',
                       user='user',
                       password='pass')
cur = conn.cursor()    
rank_scores = """SELECT x.*, @curRank := @curRank + 1 AS rank
                            FROM (
                                SELECT c.id, c.score, i.sheetscore
                                FROM chart c 
                                LEFT JOIN indicator i ON c.indicator_id = i.id
                                ORDER BY c.score DESC, i.sheetscore DESC
                            ) x
                            CROSS JOIN (SELECT @curRank :=0) q
                            ORDER BY score DESC, sheetscore DESC ;"""
 df_scorerank = pd.read_sql(rank_scores, conn)
 conn.close()
 cur.close()

第 2 步 - 从 Pandas 数据框中提取您需要的排名:

chart_rank = df_scorerank.loc[df_scorerank['id'] == chart_id, 'rank'].item()

如上,数据框现在包含:

'ID','SCORE','SHEETSCORE', 'RANK'
'11767', '1', '0.7325', '1'
'11765', '1', '0.7325', '2'
'8365', '1', '0.6925', '3'
'8363', '1', '0.6925', '4'
'8615', '1', '0.6875', '5'
'8617', '1', '0.6875', '6'
'11646', '1', '0.685455', '7'
'11647', '1', '0.685455', '8'

【讨论】:

    猜你喜欢
    • 2011-05-30
    • 2013-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-02
    • 2011-08-24
    • 1970-01-01
    相关资源
    最近更新 更多