问题描述
我有一个像这样的桌子:
### Table name: studentresult ###
Name Cls Roll Mark result Rank
Jubayer 10 1 600 Pass
Jewel 10 2 620 Pass
James 10 3 590 Pass
Jemi 10 4 590 Pass
Kalis 10 5 449 Fail
Lelin 10 6 600 Pass
我想自动生成学生的排名。排名将取决于分数(分数越高表示排名越高)。如果两个学生(或更多)具有相同的分数,则该卷将确定相对排名(较低的卷表示较好的排名)。最后,如果学生不及格,他将不会进入排名。
在我的示例中,结果将如下所示:
Name Cls Roll Mark result Rank
Jubayer 10 1 600 Pass 2
Jewel 10 2 620 Pass 1
James 10 3 590 Pass 4
Jemi 10 4 590 Pass 5
Kalis 10 5 449 Fail **
Lelin 10 6 600 Pass 3
解决方法
SELECT
name,Cls,Roll,Mark,CASE WHEN t.result LIKE 'Pass' THEN a.pos+1
WHEN t.result LIKE 'Fail' THEN '**'
END as Rank
FROM table t
CROSS JOIN (SELECT posexplode(split(repeat(',',70),'))) a
ORDER BY t.Roll
如果您有70个学生,这将创建70行。
,在MS Access中,您可以使用相关子查询:
select sr.*,iif(sr.result = "Pass",(select count(*)
from studentresult as sr2
where sr2.result = "Pass" and
(sr2.Mark > sr.Mark or
sr2.Mark = sr.Mark and sr2.roll <= sr.roll
)
),NULL
) as ranking
from studentresult as sr;
请注意,这使用NULL
作为失败的缺失值。这比'**'
更方便。您可以使用后者,但是您需要将数字转换为字符串,以便整个列都是字符串。 NULL
就可以了。
您可以在我的项目RowNumbers中使用通用函数 RowRank 。
要在此处发布太多代码,但请转到第 5段。排名以获取详细信息。
示例:
对 Mark 和 Roll 进行 Asc 进行排序的 Desc 有点棘手:
SELECT
studentresult.Name,studentresult.Cls,studentresult.Roll,studentresult.Mark,studentresult.Pass,IIf([Pass]='Pass',RowRank("[Mark],-[Roll]","(select * from studentresult where Pass='Pass')",[Mark],-[Roll],2),Null) AS Rank
FROM
studentresult;
输出:
,我刚刚修改了GordonLinoff先生的答案的代码。尝试以下查询...
SELECT sr.*,IIf(sr.result="Pass",(select count(*)
from Table1 as sr2
where sr2.result = "Pass" and
(sr2.Mark*10000-sr2.roll >= sr.Mark*10000-sr.roll and sr2.roll = sr2.roll
)
),Null) AS ranking
FROM Table1 AS sr;