代码之家  ›  专栏  ›  技术社区  ›  PKKid

为每个学生选择*最新*成绩信息

  •  4
  • PKKid  · 技术社区  · 16 年前

    我有两张桌子:

    STUDENT        GRADES
    ----------     ----------
    id             id
    name           person_id
    address        date
    city           test_name
    phone          grade
    

    每个学生在成绩表中都有几个条目。我想知道是否可以使用SQL(Postgres)来选择所有学生以及他们的 最新的 等级信息。我基本上想要一个如下的结果表,其中日期、测试名称和等级是最新结果(按日期)。

    LATEST_GRADES
    ----------------
    id
    name
    address
    city
    phone
    grade_id
    date
    test_name
    grade
    

    任何帮助都会非常感谢,谢谢。

    编辑:添加的解决方案查询

    SELECT * FROM
      students s
      JOIN (SELECT DISTINCT ON (person_id) person_id, date, test_name, grade
          FROM grades
          ORDER BY person_id, date DESC) g
        ON s.id = g.person_id;
    
    4 回复  |  直到 16 年前
        1
  •  1
  •   user80168    16 年前

    是的,这是可能的。你要找的条款是 DISTINCT ON “。使用它,您可以轻松地执行查询,而无需对同一个表进行子选择和多次扫描。

    在文件中,请注意 “独特于”的一部分。

        2
  •  2
  •   erikkallen    16 年前

    我认为postgre支持窗口功能,因此您应该能够执行类似的操作

    SELECT *
      FROM person p
      JOIN grades g ON grades.person_id = p.id
     WHERE row_number() OVER (PARTITION BY g.person_id ORDER BY g.date DESC) = 1
    

    编辑:显然,WHERE子句不支持窗口化函数(应该知道这一点,因为它是有意义的)。然而,这不是一个无法解决的问题:

    SELECT *
      FROM person p
      JOIN (SELECT person_id, <other_fields>, row_number() OVER (PARTITION BY person_id ORDER BY date DESC) AS rn FROM grades) g
     WHERE g.rn = 1
    

    但是,如果您的数据很大,请检查执行计划。

        3
  •  1
  •   ssakl    16 年前

    虽然我不熟悉Postgres,但我在Oracle的工作中做了很多这样的事情。下面的查询可能会有所帮助。

    select p.id,
           p.name,
           p.address,
           p.city,
           p.phone,
           g.date,
           g.test_name,
           g.grade 
    from person p, 
         grades g
    where p.id = g.person_id 
      and g.date = (select max(g2.date) 
                         from grades g2
                         where g2.id = g.id
                    )
    
        4
  •  0
  •   Joe Koberg    16 年前
    select 
    S.id, 
    S.name, 
    S.address, 
    S.city, 
    S.phone, 
    G.id as grade_id, 
    G.date,
    G.test_name,
    G.grade
    
    from
       Grades G,
       Student S, 
       (select S.id as studentid, max(date) as latest_grade_date  
        from student S , grades G where s.id = g.person_id) Q
    WHERE
       G.person_id = Q.studentid
       AND S.id = Q.studentid
       AND G.date = Q.latest_grade_date
       AND S.id = G.person_id