Выбор только определенных строк на основе рассчитанного значения - PullRequest
0 голосов
/ 10 октября 2019

У меня есть таблица, похожая на:

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

Я хочу рассчитать изменение среднего балла за месяц на одного учащегося - выбирая только те строки, где наблюдалось фактическое изменение. Мой желаемый вывод:

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

Пока у меня есть следующий запрос (упрощенный, но похожий):

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;

Вывод, который я получаю из этого:

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

Я полагаю, что подзапрос необходим только для выбора строк, где Change != 1, но я не уверен, как правильно реализовать это здесь.

Ответы [ 2 ]

2 голосов
/ 10 октября 2019

Вы, кажется, хотите:

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;
1 голос
/ 10 октября 2019

Очень похоже на Гордона, но использует дополнительный 3-й параметр для 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
;

Редактировать: Яне уверен, каким может быть минимальное значение ГПД, но лучше знать, что предыдущий ГПД, равный 0, приведет к ошибке деления на ноль.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...