【问题标题】:How to filter result set based on unique column and highest volume in separate column?如何根据唯一列和单独列中的最高量过滤结果集?
【发布时间】:2021-06-25 02:02:31
【问题描述】:

标题可能令人困惑。不确定如何将我的问题用语言表达出来。这是我正在使用的 SQL 语句:

SELECT * FROM (
   select * from course_student
   order by cnum ASC,
            year desc,
            case semester
               when 'Spring' then 1
               when 'Summer' then 2
               when 'Fall' then 3
            end DESC
   ) AS example
WHERE example.sid = 1
AND example.grade != 'I';

这是该查询的结果:

SID  CNUM       GRADE  SEMESTER  YEAR
1    "CPS441"   "A"   "Fall"     2013
1    "CPS441"   "D"   "Spring"   2012
1    "CPS442"   "B"   "Summer"   2013
1    "CPS445"   "A"   "Spring"   2013

基本上,我正在抓住特定学生上过的每一门课。在这一点上,我想修剪第一次出现之后的每个重复结果(因为最高结果将是该课程的最新尝试)。所以在这种情况下,我希望从结果集中过滤掉第二个等级为“D”的 CPS441 类,并留下以下内容:

SID  CNUM       GRADE  SEMESTER  YEAR
1    "CPS441"   "A"   "Fall"     2013
1    "CPS442"   "B"   "Summer"   2013
1    "CPS445"   "A"   "Spring"   2013

另一个例子是,如果我从这个开始:

SID  CNUM       GRADE  SEMESTER  YEAR
1    "CPS441"   "A"   "Fall"     2013
1    "CPS441"   "D"   "Spring"   2012
1    "CPS442"   "B"   "Summer"   2013
1    "CPS442"   "C"   "Spring"   2013
1    "CPS445"   "A"   "Spring"   2013

我想这样结束:

SID  CNUM       GRADE  SEMESTER  YEAR
1    "CPS441"   "A"   "Fall"     2013
1    "CPS442"   "B"   "Summer"   2013
1    "CPS445"   "A"   "Spring"   2013

【问题讨论】:

    标签: sql postgresql greatest-n-per-group


    【解决方案1】:

    DISTINCT ON的教科书案例:

    SELECT DISTINCT ON (cnum) *
    FROM   course_student
    ORDER  BY cnum
            , year DESC
            , CASE semester
                WHEN 'Fall'   THEN 1
                WHEN 'Summer' THEN 2
                WHEN 'Spring' THEN 3
              END
    WHERE  sid = 1
    AND    grade <> 'I';
    

    见:

    有一点不清楚: 如果最近的事件没有sid = 1 AND grade &lt;&gt; 'I',您宁愿将学生从结果中完全删除吗?或者只是删除这些行并为同一个学生获取第一个有效行(就像我的解决方案一样)?

    无论哪种方式,没有有效行的学生都不在结果中。

    【讨论】:

      【解决方案2】:

      你似乎想要row_number()

      select * 
      from (select cs.*,
                   row_number() over (partition by sid, cnum
                                      order by year desc,
                                               case semester when 'Spring' then 1 when 'Summer' then 2 when 'Fall' then 3 end desc
                                     ) as seqnum 
            from course_student
            where grade <> 'I' and sid = 1
           ) cs
      where seqnum = 1;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-01-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-11-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多