[英]get all students who has got more marks than the average marks of that class
我在下面有两个名为tbl_student
的表,我们在其中存储学生的数据,例如 id、name、class、roll no。 和年龄,以及tbl_marks
我们存储考试得分的地方。 -
CREATE TABLE IF NOT EXISTS public.tbl_student
(
student_id integer NOT NULL GENERATED ALWAYS AS IDENTITY,
student_name varchar(255) NOT NULL,
student_class integer,
student_roll_no integer,
age integer,
CONSTRAINT tbl_student_pkey PRIMARY KEY (student_id)
)
和
CREATE TABLE IF NOT EXISTS public.tbl_marks
(
marks_id integer NOT NULL GENERATED ALWAYS AS IDENTITY,
student_id integer NOT NULL,
subject varchar(255),
marks integer,
CONSTRAINT tbl_marks_pkey PRIMARY KEY (marks_id)
)
这些是各个表的一些数据:
INSERT INTO
public.tbl_student (student_name, student_class, student_roll_no, age)
VALUES
('John Doe',5,1, 12),
('Clark Keny', 5,2, 10),
('Ross Barkley', 5, 3, 11),
('Frank Lampard', 5, 4, 9),
('John Terry', 5, 5, 10),
('Peter Parker',6,1, 13),
('Tony Stark', 6,2,11),
('Bruce Wayne', 6, 3,14),
('Johnny Depp', 6, 4,11),
('Jackie Chan',7,1,15),
('John Wick', 7,2,14),
('Indiana Jones', 7, 3,11),
('Halley Berry', 7, 4,12),
('Jane Doe', 7, 5,15),
('Martha Kent', 7, 6,13);
和
INSERT INTO
public.tbl_marks (student_id, subject, marks)
VALUES
(1, 'Math' , 79),
(1, 'Science' , 64),
(2, 'Math' , 69),
(2, 'Science' , 72),
(3, 'Math' , 30),
(3, 'Science' , 50),
(4, 'Math' , 77),
(4, 'Science' , 72),
(5, 'Math' , 84),
(5, 'Science' , 88),
(6, 'Math' , 36),
(6, 'Science' , 54),
(7, 'Math' , 55),
(7, 'Science' , 54),
(8, 'Math' , 66),
(8, 'Science' , 78),
(9, 'Math' , 43),
(9, 'Science' , 20),
(10, 'Math' ,87 ),
(10, 'Science' , 92),
(11, 'Math' , 68),
(11, 'Science' , 82),
(12, 'Math' , 78),
(12, 'Science' , 93),
(13, 'Math' , 20),
(13, 'Science' , 22),
(14, 'Math' , 40),
(14, 'Science' , 42),
(15, 'Math' , 52),
(15, 'Science' , 62);
现在,我需要让每个 class 中所有分数高于各自班级平均分数的学生。
我使用带有PARTITION BY
子句的RANK()
function 进行了尝试。
尝试这个:
SELECT a.*
FROM
( SELECT s.*
, m.subject
, m.marks
, avg(m.marks) OVER (PARTITION BY m.subject, s.student_class) AS marks_avg
FROM tbl_marks AS m
INNER JOIN tbl_student AS s
ON s.student_id = m.student_id
) AS a
WHERE a.marks > a.marks_avg
在dbfiddle中查看结果。
请参阅有关 window 功能的手册:
https://www.postgresql.org/docs/current/tutorial-window.html https://www.postgresql.org/docs/current/queries-table-expressions.html#QUERIES-WINDOW https://www. postgresql.org/docs/current/functions-window.html
还有关于可以用作 window 函数的聚合函数:
https://www.postgresql.org/docs/current/sql-expressions.html#SYNTAX-AGGREGATES https://www.postgresql.org/docs/current/functions-aggregate.html
好的,所以找到平均值是这样的:
SELECT s.student_class, m.subject, AVG(m.marks) AS average
FROM tbl_marks m INNER JOIN tbl_student s USING (student_id)
GROUP by s.student_class, m.subject
所以,我们只需要将它用作连接中的另一个表:
SELECT DISTINCT s.student_name, s.student_class, m.subject, m.marks
FROM tbl_marks m
INNER JOIN tbl_student s USING (student_id)
INNER JOIN (
SELECT s.student_class, m.subject, AVG(m.marks) AS average
FROM tbl_marks m INNER JOIN tbl_student s USING (student_id)
GROUP by s.student_class, m.subject) x1
USING (student_class, subject)
WHERE m.marks >= x1.average;
Output:
John Doe 5 Math 79
Clark Keny 5 Math 69
Clark Keny 5 Science 72
Frank Lampard 5 Math 77
Frank Lampard 5 Science 72
John Terry 5 Math 84
John Terry 5 Science 88
Peter Parker 6 Science 54
Tony Stark 6 Math 55
Tony Stark 6 Science 54
Bruce Wayne 6 Math 66
Bruce Wayne 6 Science 78
Jackie Chan 7 Math 87
Jackie Chan 7 Science 92
John Wick 7 Math 68
John Wick 7 Science 82
Indiana Jones 7 Math 78
Indiana Jones 7 Science 93
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.