说我有这样一张桌子:
S_id |ca1 |ca2 |exam
1 | 08 | 12 | 35
1 | 02 | 14 | 32
1 | 08 | 12 | 20
2 | 03 | 11 | 55
2 | 09 | 18 | 45
2 | 10 | 12 | 35
3 | 07 | 12 | 35
3 | 04 | 14 | 37
3 | 09 | 15 | 32
4 | 03 | 11 | 55
4 | 09 | 18 | 45
4 | 10 | 12 | 35
5 | 10 | 12 | 35
5 | 07 | 12 | 35
5 | 09 | 18 | 45
我想选择S_id,total并根据总和(ca1 + ca2 +考试)为每个学生分配一个等级,如下所示:
S_id |total|rank
1 | 158 | 5
2 | 198 | 1
3 | 165 | 4
4 | 198 | 1
5 | 183 | 3
如果总排名相同,例如S_id
2和S_id
4排名为1,我希望将排名跳至3。
感谢您的帮助。
答案 0 :(得分:2)
制作表格:
sqlite> create table t (S_id, ca1, ca2, exam);
sqlite> insert into t values
...> ( 1 , 08 , 12 , 35 ),
...> ( 1 , 02 , 14 , 32 ),
...> ( 1 , 08 , 12 , 20 ),
...> ( 2 , 03 , 11 , 55 ),
...> ( 2 , 09 , 18 , 45 ),
...> ( 2 , 10 , 12 , 35 ),
...> ( 3 , 07 , 12 , 35 ),
...> ( 3 , 04 , 14 , 37 ),
...> ( 3 , 09 , 15 , 32 ),
...> ( 4 , 03 , 11 , 55 ),
...> ( 4 , 09 , 18 , 45 ),
...> ( 4 , 10 , 12 , 35 ),
...> ( 5 , 10 , 12 , 35 ),
...> ( 5 , 07 , 12 , 35 ),
...> ( 5 , 09 , 18 , 45 );
制作一个总分数的临时表:
sqlite> create temp table tt
as select S_id, sum(ca1) + sum(ca2) + sum(exam) as total
from t group by S_id;
使用临时表计算排名:
sqlite> select s.S_id, s.total,
(select count(*)+1 from tt as r where r.total > s.total) as rank
from tt as s;
1|143|5
2|198|1
3|165|4
4|198|1
5|183|3
删除临时表:
sqlite> drop table tt;
附录
最近对SQLite进行了更改(2015-02-09),此配方现在可以使用:
with tt (S_id, total) as
(select S_id, sum(ca1 + ca2 + exam) as total from t group by S_id)
select s.S_id, s.total,
(select count(*)+1 from tt as r where r.total > s.total) as rank
from tt as s;
答案 1 :(得分:1)
这样的事情可能是:
with tt(S_id,total) as (
select S_id, sum(ca1) + sum(ca2) + sum(exam)
from t
group by S_id
union
select null, 0
)
select s.S_id,
s.total,
(select count(*)+1
from tt as r
where r.total > s.total) as rank
from tt as s
where S_id is not null;
答案 2 :(得分:1)
根据我的标准Rank Rows回答,使用自我加入:
with tt (S_id, total) as
(select S_id, sum(ca1 + ca2 + exam) as total
from t group by S_id)
select S.S_id, S.total, 1+count(lesser.total) as RANK
from tt as S
left join tt as lesser
on S.total < lesser.total
group by S.S_id, S.total
order by S.total desc;
S_id total RANK
---------- ---------- ----------
2 198 1
4 198 1
5 183 3
3 165 4
1 143 5
你不需要CTE;您可以使用子查询,但您必须重复它。
使用SELECT子句中的SELECT子句生成列(如其他地方所建议的那样)是AFAIK非标准。自联接是标准的,并且查询计划程序应该更容易优化(仅限于此原因)。此外,上述查询并未对数据进行处理:它不会向CTE添加行,只能在主查询中删除它。
我更喜欢sum(ca1 + ca2 + exam)
构造来添加总和。这就是提出问题的方式,要求系统做更少的工作(只有一次总结)。当然,添加是可交换的,但我不会依赖查询优化器来注意。