简体   繁体   English

仅根据计算值选择某些行

[英]Only selecting certain rows based on calculated value

I have a table similar to:我有一个类似的表:

-----------------------
|Student| Month| GPA   |
---------------------
|   1   |  1   |  70   |
|   1   |  2   |  70   | 
|   1   |  3   |  75   |
|   2   |  1   |  80   |
|   2   |  2   |  72   |
|   2   |  3   |  72   |

What I want, is to calculate the GPA change, per month, per student - only selecting rows where an actual change was observed.我想要的是计算每个学生每月的 GPA 变化 - 只选择观察到实际变化的行。 My desired output is:我想要的 output 是:

-----------------------
|Student| Month| GPA   |
---------------------
|   1   |  3   |  1.071|
|   2   |  2   |  0.9  | 

So far I have the following query (simplified, but similar):到目前为止,我有以下查询(简化,但类似):

SELECT
    Student,
    Month,
    GPA,
    Change =
    CASE
        WHEN LAG(GPA, 1) OVER (ORDER BY Student, Month) !> 0 
            THEN 1
        WHEN Student != LAG(Student, 1) OVER (ORDER BY Student, Month)             
            THEN 1
        ELSE GPA/LAG(GPA, 1) OVER (ORDER BY Student, Month)
FROM students
ORDER BY Student, Month;

The output I receive from this is:我收到的 output 是:

---------------------------------
|Student| Month| GPA   |  Change|
---------------------------------
|   1   |  1   |  70   |   1    |
|   1   |  2   |  70   |   1    |
|   1   |  3   |  75   |   1.071|
|   2   |  1   |  80   |   1    |
|   2   |  2   |  72   |   0.9  |
|   2   |  3   |  72   |   1    |

I believe a sub-query is needed to only select rows where Change != 1 , but I'm unsure how to implement this correctly here.我相信子查询只需要 select 行 where Change != 1 ,但我不确定如何在这里正确实现。

You seem to want:你似乎想要:

select s.*,
       gpa / nullif(prev_gpa, 0)  -- I suppose a 0 gpa is possible
from (select s.*,
             lag(gpa) over (partition by student order by month) as prev_gpa
      from s
     ) s
where prev_gpa is not null and prev_gpa <> gpa;

Very similar to Gordon's, but takes advantage of the optional 3rd parameter to LAG to use the current row's GPA when there is no previous (to yield no change).与 Gordon 的非常相似,但利用 LAG 的可选第三个参数在没有前一个的情况下使用当前行的 GPA(不产生任何变化)。

SELECT * 
FROM (
   SELECT Student, Month, GPA
     , Change = GPA / LAG(GPA, 1, GPA) OVER (PARTITION BY Student ORDER BY Month)
   FROM students
) AS subQ
WHERE Change != 1.0
ORDER BY Student, Month
;

Edit: I'm not sure what the minimum GPA value could be, but it is best to be aware that a previous GPA of 0 would cause a divide by zero error.编辑:我不确定最小 GPA 值可能是多少,但最好知道之前的 GPA 为 0 会导致除以零错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM