给出一个名为"grade"的表:
STUDENT GRADE
john 94
john 76
john 83
john 87
john 90
Run Code Online (Sandbox Code Playgroud)
我想要一个查询来返回每个学生的几个成绩示例,例如:
STUDENT GRADE1 GRADE2 GRADE3 GRADE4
John 94 76 83 87
Run Code Online (Sandbox Code Playgroud)
请注意,只返回了4个样本成绩列,但该学生的成绩超过4个.
我只知道如何使用GROUP BY子句中的min()和max()函数返回2个示例等级:
select student, min(grade), max(grade)
from grades
group by student
Run Code Online (Sandbox Code Playgroud)
除了min/max之外,是否有任何技巧或功能可以使用GROUP BY子句显示超过2个等级?
除非它是查询的一部分而不是存储在数据库中,否则我宁愿不编写自己的存储函数来执行此操作.
我想更多的函数除了MIN和MAX之外还从记录集返回其他值(比如第二高,第三高等).
想法?
您可以通过应用row_number()函数然后应用PIVOT 来获得结果:
select student,
grade1 = [1],
grade2 = [2],
grade3 = [3],
grade4 = [4]
from
(
select student, grade,
row_number() over(partition by student
order by grade desc) seq
from grades
) d
pivot
(
max(grade)
for seq in ([1], [2], [3], [4]) -- the # of grades you want returned
) piv;
Run Code Online (Sandbox Code Playgroud)
PIVOT中使用的新列名称将是您想要返回的等级数.该ORDER BY分区中的使用感是grade desc的,但你也可以看看使用order by newid()即可返回随机结果.
这也可以使用带有CASE表达式的聚合函数来完成:
select student,
max(case when seq = 1 then grade end) grade1,
max(case when seq = 2 then grade end) grade2,
max(case when seq = 3 then grade end) grade3,
max(case when seq = 4 then grade end) grade4
from
(
select student, grade,
row_number() over(partition by student
order by newid()) seq
from grades
) d
group by student;
Run Code Online (Sandbox Code Playgroud)
我提出这样的建议。唯一的限制是您不能显示示例 1 到 n,您只能显示确定的数量。
SELECT DISTINCT student,
(
select top 1 grade from
(select grade, ROW_NUMBER() OVER(ORDER BY grade DESC) AS Row from grades g2 where g.student = g2.student) a where a.Row = 1
) AS GRADE1 ,
(
select top 1 grade from
(select grade, ROW_NUMBER() OVER(ORDER BY grade DESC) AS Row from grades g2 where g.student = g2.student) a where a.Row = 2
) AS GRADE2,
(
select top 1 grade from
(select grade, ROW_NUMBER() OVER(ORDER BY grade DESC) AS Row from grades g2 where g.student = g2.student) a where a.Row = 3
) AS GRADE3,
(
select top 1 grade from
(select grade, ROW_NUMBER() OVER(ORDER BY grade DESC) AS Row from grades g2 where g.student = g2.student) a where a.Row = 4
) AS GRADE4
from grades g
Run Code Online (Sandbox Code Playgroud)
带光标。在此解决方案中,您将得到 1 到 n 个结果
DECLARE @grade int
DECLARE @n int
DECLARE @sql varchar(max)
DECLARE _cursor CURSOR FOR
SELECT grade
FROM grade
WHERE student like 'XXX'
OPEN _cursor
FETCH NEXT FROM _cursor INTO @grade
WHILE @@FETCH_STATUS = 0
BEGIN
IF @sql like ''
begin
set @sql = 'SELECT ' + 'XXX' + ' AS Student '
end
set @sql = @sql + ',' + @grade ' as GRADE'+ @n
set @n = @n + 1
END
CLOSE _cursor
DEALLOCATE _cursor
exec(@sql)
Run Code Online (Sandbox Code Playgroud)
这个输出将是
STUDENT GRADE1 GRADE2 GRADE3 GRADE4
John 94 87 83 76
Run Code Online (Sandbox Code Playgroud)