简体   繁体   中英

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. My desired output is:

-----------------------
|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:

---------------------------------
|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.

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).

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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