PostgreSQL-通过比较组中的行进行搜索

时间:2019-03-30 06:28:17

标签: sql postgresql

表格-grades

create table grades
(
  student_id bigserial                           not null,
  course_id  bigserial                           not null,
  score      int                                 not null,
  created    timestamp default CURRENT_TIMESTAMP not null,
  unique (student_id, course_id)
);

所需结果:

  

查找所有学生的ID(课程1>课程2)。

示例数据:

INSERT INTO grades(student_id, course_id, score)
VALUES (1, 1, 60),
       (1, 2, 70),
       (1, 3, 65),
       (2, 1, 70),
       (2, 2, 60),
       (2, 3, 80),
       (3, 1, 90),
       (3, 2, 90),
       (3, 3, 85);

尝试了什么

想法:

  • 为学生创建一个tmp表,每行包含两个分数。
    gm student_id, score_1, score_2
  • 然后从tmp表中查询,条件为score_1 > score_2

查询:

select *
from (
       select grades_1.student_id as sid, grades_1.score as score_1, grades_2.score as score_2
       from (select student_id, score from grades where course_id = 1 order by student_id) as grades_1
              inner join
            (select student_id, score from grades where course_id = 2 order by student_id) as grades_2
            on grades_1.student_id = grades_2.student_id
     ) as gm
where gm.score_1 > gm.score_2;

问题是:

  • 是否有更好的解决方案? (对于Postgresql,尤其重要)。
  • 如果查询需要比较3个或更多的课程,是否还有其他更有意义的解决方案?
    例如course 1 > course 2 > course 3

1 个答案:

答案 0 :(得分:3)

我们可以尝试使用简单的枢轴来隔离和比较各个课程的成绩:

SELECT
    student_id,
    MAX(score) FILTER (WHERE course_id = 1) AS course_1_score,
    MAX(score) FILTER (WHERE course_id = 2) AS course_2_score
FROM grades
GROUP BY
    student_id
HAVING
    MAX(score) FILTER (WHERE course_id = 1) >
    MAX(score) FILTER (WHERE course_id = 2);

您可以在HAVING子句中添加另一个术语以比较其他课程成绩。