【问题标题】:In PostgreSQL, in a table with multiple rows per unique ID, can you select one row by a condition per unique ID and other values?在 PostgreSQL 中,在每个唯一 ID 具有多行的表中,您可以通过每个唯一 ID 和其他值的条件选择一行吗?
【发布时间】:2021-03-02 02:39:47
【问题描述】:

具体来说,我是一个测试数据表,我试图在其中为每个学生和每个会话(即秋季、冬季、春季)选择一行数据。问题是有一些学生在同一个会话中重新参加了考试,我希望我的查询能够处理这些事件。

假设一个学生(学生 ID = 12345)在秋季参加了 两次 考试 - 一次是在 9 月 23 日,成绩为 85/100,然后在 10 月 3 日再次参加考试,成绩为75/100。我想知道两个不同的查询,一个用于处理以下各项:

  1. 返回他们最近的测试(即 10 月 3 日的测试)所在的行
  2. 返回他们得分最高的测试的行(即从 9 月 23 日开始的测试)

这是一个类似于我正在使用的表格的示例:

| studentid | session | testdate     | score | schoolyear |
-----------------------------------------------------------
| ...                                        
| 42532     | Fall    | '2020-10-01' | 68    | '2020-2021'
| 42532     | Winter  | '2021-02-02' | 70    | '2020-2021'
| 12345     | Fall    | '2020-09-23' | 85    | '2020-2021' <--- (this student has two records for the fall)
| 12345     | Fall    | '2020-10-03' | 75    | '2020-2021' <---
| 12345     | Winter  | '2021-01-10' | 79    | '2020-2021'
| 83456     | Fall    | '2020-09-08' | 90    | '2019-2020'
| 83456     | Winter  | '2021-01-18' | 83    | '2019-2020'
| ...                                        

所以我想运行类似于以下的查询:

SELECT studentid, session, testdate, score
FROM exam_result
WHERE schoolyear = '2020-2021'
-- (something to filter out the multiples)

对于所有学生,每个学生 AND 会话返回 1 行 任何帮助将不胜感激!

【问题讨论】:

  • 编辑您的问题并显示您想要的结果。

标签: sql postgresql aggregate


【解决方案1】:

如果您只想要一行,请使用fetchlimit

select er.*
from exam_result er
where er.studentid = 12345
order by testdate desc
limit 1;

只需为您想要的行调整order by

对于所有测试,您将使用 distinct on:

select distinct on (er.studentid) er.*
from exam_result er
where . . . -- whatever other conditions you have
order by er.studentid, testdate desc

【讨论】:

  • 不,不想只返回一个学生的数据。我要所有的学生。所以基本上是一个回答以下问题的查询:“获取所有学生的数据以及他们在秋季和冬季参加的考试。但如果他们在一个会话中多次参加考试,则只返回最新日期的考试(或最高分的考试) "
  • 您答案的第二部分效果很好!谢谢。
【解决方案2】:

你更喜欢哪个分数;最好的或最坏的还是别的什么?这个查询给你最好的分数。我放弃了 testdate ,因为它不是唯一的。如果您需要测试日期,它会使查询更加复杂。如果学生两次获得相同的分数,你想要什么日期?

SELECT studentid, session, MAX(score)
FROM exam_result
WHERE schoolyear = '2020-2021'
GROUP BY studentid, session

如果您需要考试日期,这种查询会为您提供学生获得最高分的第一个考试日期。这没有经过测试,但你明白了。制作单独的子查询,获取学生/分数组合的最小日期,并将其加入您的原始查询。

SELECT
 a.student_id.
 a.session,
 b.exam_date,
 a.score
FROM
 exam_resut a JOIN
   (SELECT 
      student_id, session, MIN(exam_date) 
    FROM exam_result 
    WHERE schoolyear = '2020-2021' 
    GROUP BY student_id, session) b 
        ON a.studet_id = b.student_id and a.session = b.sesion
WHERE a.schoolyear = '2020-2021'
GROUP BY a.studentid, a.session, b.exam_date

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-03
    • 2021-08-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多