我正在尝试从表中选择多个列,但我想根据一列选择最多一定数量的记录。我试过这个:
select roll_no ,marks as Percentage
from database
where marks in (select top (3) *
from database
where subject = ''
order by marks desc) order by percentage desc
我收到错误:
当选择列表中只能指定一个表达式时 子查询不是用EXISTS引入的,也不是超过指定的数字 记录。
我也尝试过:
select roll_no ,marks as Percentage
from database
where marks in (select top (3) marks
from database
where subject = ''
order by marks desc) order by percentage desc
为某些科目返回正确的结果,但对于其他科目,则会显示其他科目的最高分。
例如:
+---------+-------+
| roll_no | marks |
+---------+-------+
|10003 | 87 |
|10006 | 72 |
|10003 | 72 |
|10002 | 67 |
|10004 | 67 |
+---------+-------+
如何正确构建查询?
示例数据:
+---------+-------+---------+
| roll_no | marks |subject |
+---------+-------+---------+
|10001 | 45 | Maths |
|10001 | 72 | Science |
|10001 | 64 | English |
|10002 | 52 | Maths |
|10002 | 35 | Science |
|10002 | 75 | English |
|10003 | 52 | Maths |
|10003 | 35 | Science |
|10003 | 75 | English |
|10004 | 52 | Maths |
|10004 | 35 | Science |
|10004 | 75 | English |
+---------+-------+---------+
答案 0 :(得分:0)
您可以使用窗口函数对marks
列进行排名(具体为dense_rank
,允许重复排名,同时保留顺序编号),然后返回排名为3
或更少的所有行:
declare @t table(roll_no int identity(1,1),marks int);
insert into @t(marks) values(2),(4),(5),(8),(6),(1),(3),(2),(1),(8);
with t as
(
select roll_no
,marks
,dense_rank() over (order by marks desc) as r
from @t
)
select *
from t
where r <= 3;
输出:
+---------+-------+---+
| roll_no | marks | r |
+---------+-------+---+
| 4 | 8 | 1 |
| 10 | 6 | 1 |
| 5 | 6 | 2 |
| 3 | 5 | 3 |
+---------+-------+---+
答案 1 :(得分:0)
如果我是对的并且您正在为每个主题寻找最佳的3分,那么您可以通过以下方式获得它:
DECLARE @SelectedSubject VARCHAR(50) = 'Maths'
;WITH FilteredSubjectMarks AS
(
SELECT
D.Subject,
D.Roll_no,
D.Marks,
MarksRanking = DENSE_RANK() OVER (ORDER BY D.Marks DESC)
FROM
[Database] AS D
WHERE
D.Subject = @SelectedSubject
)
SELECT
F.*
FROM
FilteredSubjectMarks AS F
WHERE
F.MarksRanking <= 3