按 select 个结果组添加排名列
Add Rank column by select result group
我有一个名为 myTable 的 table,其中包含参与者列表和他们在每个测试中的分数。
-----------------------------------------
id_test id_paticipant score
-----------------------------------------
id_test1 Partcipant1 100
id_test1 Partcipant2 200
id_test1 Partcipant3 150
id_test1 Partcipant4 300
id_test2 Partcipant1 500
id_test2 Partcipant3 250
id_test3 Partcipant2 70
id_test3 Partcipant3 150
id_test3 Partcipant4 420
id_test4 Partcipant1 120
id_test4 Partcipant2 200
我想要一个允许我有一个排名列的请求,我将在每个测试中获得每个参与者的排名,如下面的 table。
-----------------------------------------------
id_test id_paticipant score rank
-------------------------------------------------------
id_test1 Partcipant1 100 4
id_test1 Partcipant2 200 2
id_test1 Partcipant3 150 3
id_test1 Partcipant4 300 1
id_test2 Partcipant1 500 1
id_test2 Partcipant3 250 2
id_test3 Partcipant2 70 3
id_test3 Partcipant3 150 2
id_test3 Partcipant4 420 1
id_test4 Partcipant1 120 2
id_test4 Partcipant2 200 1
---------------------------------------------
我试过这个:
SET @prev_id_test := 0;
SET @curRow := 1;
select t2.id_test, t2.id_partcipant, t2.score
,if(t2.id_test=@prev_id_test, @curRow := @curRow + 1, @curRow := 1) AS rank, @prev_id_test := t2.id_test
from (select myTable.* from myTable order by myTable.id_test, myTable.score desc) as t2
order by t2.id_test, t2.score, t2.id_partcipant desc;
但这行不通,我的排名是降序排列的,我的意思是分数最低的排名是 1,等等...比如:
-----------------------------------------------
id_test id_paticipant score rank
-----------------------------------------------
id_test1 Partcipant1 100 1
id_test1 Partcipant2 200 3
id_test1 Partcipant3 150 2
id_test1 Partcipant4 300 4
id_test2 Partcipant1 500 2
id_test2 Partcipant3 250 1
id_test3 Partcipant2 70 1
id_test3 Partcipant3 150 2
id_test3 Partcipant4 420 3
id_test4 Partcipant1 120 1
id_test4 Partcipant2 200 2
---------------------------------------------
有人可以帮忙吗?
提前致谢
试试这个版本:
select t.*,
(@rn := if(@it = t.id_test, @rn + 1,
if(@it := t.id_test, 1, 1)
)
) as rank
from (select t.*
from myTables t
order by id_test, score desc
) t cross join
(select @it := -1, @rn := 0) params;
有什么区别?您的版本正在分配变量并在不同的表达式中引用它们。 MySQL(或任何其他数据库)保证 SELECT
中表达式的求值顺序。所以,你不知道哪个先发生。
并且,MySQLv8+ 最终不再需要使用变量。它与 SQL 社区的其他成员一起支持 window 功能。这将逻辑简化为:
row_number() over (partition by test_id order by score_desc) as ranking
我现在想添加其他 3 列:
- Max,其中包含每个组的最大分数,
- Min 包含每组的最小分数,
- 和包含每组平均分数的平均值
像这样 table 显示在这里:
------------------------------------------------------------------------
id_test id_participant score rank Max Min average
------------------------------------------------------------------------
id_test1 Partcipant1 100 4 300 100 187.5
id_test1 Partcipant2 200 2 300 100 187.5
id_test1 Partcipant3 150 3 300 100 187.5
id_test1 Partcipant4 300 1 300 100 187.5
id_test2 Partcipant1 500 1 500 250 375
id_test2 Partcipant3 250 2 500 250 375
id_test3 Partcipant2 70 3 420 70 213.33
id_test3 Partcipant3 150 2 420 70 213.33
id_test3 Partcipant4 420 1 420 70 213.33
id_test4 Partcipant1 120 2 200 120 160
id_test4 Partcipant2 200 1 200 120 160
------------------------------------------------------------------------
我试试这个:
select
t.*,
(@rn := if(@it = t.id_test, @rn + 1,if(@it := t.id_test, 1, 1))) as rank,
(select max(t1.score) from myTables t1 group by t1.id_test) as Max,
(select min(t1.score) from myTables t1 group by t1.id_test) as Max,
(select round((sum(t1.score)/count(t1.id_participant)), 2) from myTables t1 group by t1.id_test) as average
from
(select t.*
from myTables
order by t.id_test, t.score desc) as t
cross join
(select @it := -1, @rn := 0) params;
但是我得到这个错误:
Can't reopen table
我认为这是由于 table myTable 是一个临时的 table。
你有什么想法吗?
谢谢
我有一个名为 myTable 的 table,其中包含参与者列表和他们在每个测试中的分数。
-----------------------------------------
id_test id_paticipant score
-----------------------------------------
id_test1 Partcipant1 100
id_test1 Partcipant2 200
id_test1 Partcipant3 150
id_test1 Partcipant4 300
id_test2 Partcipant1 500
id_test2 Partcipant3 250
id_test3 Partcipant2 70
id_test3 Partcipant3 150
id_test3 Partcipant4 420
id_test4 Partcipant1 120
id_test4 Partcipant2 200
我想要一个允许我有一个排名列的请求,我将在每个测试中获得每个参与者的排名,如下面的 table。
-----------------------------------------------
id_test id_paticipant score rank
-------------------------------------------------------
id_test1 Partcipant1 100 4
id_test1 Partcipant2 200 2
id_test1 Partcipant3 150 3
id_test1 Partcipant4 300 1
id_test2 Partcipant1 500 1
id_test2 Partcipant3 250 2
id_test3 Partcipant2 70 3
id_test3 Partcipant3 150 2
id_test3 Partcipant4 420 1
id_test4 Partcipant1 120 2
id_test4 Partcipant2 200 1
---------------------------------------------
我试过这个:
SET @prev_id_test := 0;
SET @curRow := 1;
select t2.id_test, t2.id_partcipant, t2.score
,if(t2.id_test=@prev_id_test, @curRow := @curRow + 1, @curRow := 1) AS rank, @prev_id_test := t2.id_test
from (select myTable.* from myTable order by myTable.id_test, myTable.score desc) as t2
order by t2.id_test, t2.score, t2.id_partcipant desc;
但这行不通,我的排名是降序排列的,我的意思是分数最低的排名是 1,等等...比如:
-----------------------------------------------
id_test id_paticipant score rank
-----------------------------------------------
id_test1 Partcipant1 100 1
id_test1 Partcipant2 200 3
id_test1 Partcipant3 150 2
id_test1 Partcipant4 300 4
id_test2 Partcipant1 500 2
id_test2 Partcipant3 250 1
id_test3 Partcipant2 70 1
id_test3 Partcipant3 150 2
id_test3 Partcipant4 420 3
id_test4 Partcipant1 120 1
id_test4 Partcipant2 200 2
---------------------------------------------
有人可以帮忙吗?
提前致谢
试试这个版本:
select t.*,
(@rn := if(@it = t.id_test, @rn + 1,
if(@it := t.id_test, 1, 1)
)
) as rank
from (select t.*
from myTables t
order by id_test, score desc
) t cross join
(select @it := -1, @rn := 0) params;
有什么区别?您的版本正在分配变量并在不同的表达式中引用它们。 MySQL(或任何其他数据库)保证 SELECT
中表达式的求值顺序。所以,你不知道哪个先发生。
并且,MySQLv8+ 最终不再需要使用变量。它与 SQL 社区的其他成员一起支持 window 功能。这将逻辑简化为:
row_number() over (partition by test_id order by score_desc) as ranking
我现在想添加其他 3 列:
- Max,其中包含每个组的最大分数,
- Min 包含每组的最小分数,
- 和包含每组平均分数的平均值
像这样 table 显示在这里:
------------------------------------------------------------------------
id_test id_participant score rank Max Min average
------------------------------------------------------------------------
id_test1 Partcipant1 100 4 300 100 187.5
id_test1 Partcipant2 200 2 300 100 187.5
id_test1 Partcipant3 150 3 300 100 187.5
id_test1 Partcipant4 300 1 300 100 187.5
id_test2 Partcipant1 500 1 500 250 375
id_test2 Partcipant3 250 2 500 250 375
id_test3 Partcipant2 70 3 420 70 213.33
id_test3 Partcipant3 150 2 420 70 213.33
id_test3 Partcipant4 420 1 420 70 213.33
id_test4 Partcipant1 120 2 200 120 160
id_test4 Partcipant2 200 1 200 120 160
------------------------------------------------------------------------
我试试这个:
select
t.*,
(@rn := if(@it = t.id_test, @rn + 1,if(@it := t.id_test, 1, 1))) as rank,
(select max(t1.score) from myTables t1 group by t1.id_test) as Max,
(select min(t1.score) from myTables t1 group by t1.id_test) as Max,
(select round((sum(t1.score)/count(t1.id_participant)), 2) from myTables t1 group by t1.id_test) as average
from
(select t.*
from myTables
order by t.id_test, t.score desc) as t
cross join
(select @it := -1, @rn := 0) params;
但是我得到这个错误:
Can't reopen table
我认为这是由于 table myTable 是一个临时的 table。
你有什么想法吗?
谢谢