Как создать рейтинг MySQL 5.6 с помощью JOIN и нескольких критериев сортировки - PullRequest
0 голосов
/ 13 июля 2020

Я застрял, пытаясь вернуть ранг запроса 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

Ответы [ 2 ]

1 голос
/ 13 июля 2020

Я бы рекомендовал сначала присоединиться и упорядочить в подзапросе, а затем вычислить рейтинг. Кроме того, вы не должны смешивать неявные и явные объединения - по сути, всегда используйте явные объединения:

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
0 голосов
/ 14 июля 2020

Другой вариант:

Очень неэффективный метод определения одного или двух элементов, но хорошее решение для тех, кто работает с PANDAS и Python и имеет много похожих запросов, заключается в том, чтобы загрузить ваш запрос SQL в Dataframe, а затем использовать Pandas 'инструменты ранжирования и запроса - в 2 этапа:

Шаг 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'
...