我的项目中有下表数据。该表按行号分区。
在此表中,行号 1 表示学生在第一季度修读的类(class)。同样,行号 2 代表第二季度的类(class)。与第 3 行和第 4 行相同。我想提取类(class)和成绩的总体列表。类(class)的成绩应该是最后一次参加该类(class)的成绩。所以,结果数据表应该是这样的:
我写了下面的组查询:
SELECT
T.NAME,
T.COURSE,
T.HRSCODE,
MAX(T.GRADE) as 'GRADE'
FROM
#TEMP T
GROUP BY
T.NAME, T.COURSE, T.HRSCODE
演示:rextester.com/FSUIM64308
MAX(grade)
返回主题“数学”的错误成绩。有没有其他方法可以完成这个结果?
最佳答案
这看起来像是一个经典的每组 top-n 问题。
一种方法是使用 ROW_NUMBER
函数。
示例数据
CREATE TABLE TEMP1(ROWNUM INT,
NAME VARCHAR(50), COURSE VARCHAR(50), year int,
CAT VARCHAR(50), HRSCODE VARCHAR(30), GRADE VARCHAR(10))
insert TEMP1 values
('1' , 'STUDENT1' , 'MATH ' , 2016,'CRS1' ,'MT1.Y7' , 'A+'),
('1' , 'STUDENT1' , 'ENGLISH ' , 2016,'CRS2' ,'ENG14.JI', 'B'),
('1' , 'STUDENT1' , 'SCIENCE ' , 2016,'CRS3' ,'SCI678' , 'C'),
('1' , 'STUDENT1' , 'HISTORY ' , 2016,'CRS4' ,'HIS704' , 'A+'),
('2' , 'STUDENT1' , 'MATH ' , 2016,'CRS1' ,'MT1.Y7' , 'A-'),
('2' , 'STUDENT1' , 'ENGLISH ' , 2016,'CRS2' ,'ENG14.JI', 'B+'),
('2' , 'STUDENT1' , 'SCIENCE ' , 2016,'CRS3' ,'SCI678' , 'C+'),
('2' , 'STUDENT1' , 'HISTORY ' , 2016,'CRS4' ,'HIS704' , 'C-'),
('3' , 'STUDENT1' , 'MATH ' , 2017,'CRS1' ,'MT1.Y7' , 'A+'),
('3' , 'STUDENT1' , 'ENGLISH ' , 2017,'CRS2' ,'ENG14.JI', 'A+'),
('3' , 'STUDENT1' , 'PSYCHOLOGY ' , 2017,'CRS3' ,'PSY9.78' , 'B'),
('3' , 'STUDENT1' , 'PHYSICS ' , 2017,'CRS4' ,'PHY53.XG', 'B'),
('4' , 'STUDENT1' , 'MATH ' , 2017,'CRS1' ,'MT1.Y7' , 'A'),
('4' , 'STUDENT1' , 'ENGLISH ' , 2017,'CRS2' ,'ENG14.JI', 'C'),
('4' , 'STUDENT1' , 'PSYCHOLOGY ' , 2017,'CRS3' ,'PSY9.78' , 'B'),
('4' , 'STUDENT1' , 'PHYSICS ' , 2017,'CRS4' ,'PHY53.XG', 'C+');
请注意,您在 rextester 中的原始示例数据在类(class)名称中有制表符,我将其替换为空格。
查询
SELECT TOP(1) WITH TIES
NAME
,COURSE
,year
,CAT
,HRSCODE
,GRADE
FROM TEMP1
ORDER BY ROW_NUMBER() OVER (PARTITION BY NAME, COURSE ORDER BY year DESC, ROWNUM DESC)
;
http://rextester.com/edit/KQKP45357
结果
+----+----------+-------------+------+------+----------+-------+
| | NAME | COURSE | year | CAT | HRSCODE | GRADE |
+----+----------+-------------+------+------+----------+-------+
| 1 | STUDENT1 | ENGLISH | 2017 | CRS2 | ENG14.JI | C |
| 2 | STUDENT1 | MATH | 2017 | CRS1 | MT1.Y7 | A |
| 3 | STUDENT1 | HISTORY | 2016 | CRS4 | HIS704 | C- |
| 4 | STUDENT1 | PHYSICS | 2017 | CRS4 | PHY53.XG | C+ |
| 5 | STUDENT1 | PSYCHOLOGY | 2017 | CRS3 | PSY9.78 | B |
| 6 | STUDENT1 | SCIENCE | 2016 | CRS3 | SCI678 | C+ |
+----+----------+-------------+------+------+----------+-------+
这个查询更常见的写法是这样的:
WITH
CTE
AS
(
SELECT
ROWNUM
,NAME
,COURSE
,year
,CAT
,HRSCODE
,GRADE
,ROW_NUMBER() OVER(PARTITION BY NAME, COURSE ORDER BY year DESC, ROWNUM DESC) AS rn
FROM TEMP1
)
SELECT
NAME
,COURSE
,year
,CAT
,HRSCODE
,GRADE
FROM CTE
WHERE rn = 1
ORDER BY NAME, COURSE
;
关于sql - 按 Varchar 字段分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50284070/