Функция окна LAG в Redshift - показывает значения предыдущего года и текущего года в одной строке - PullRequest
0 голосов
/ 16 февраля 2019

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

Student City    Country Year Month Subject Marks
John    Boston  USA    2018  01    Maths   90
Mark    London  UK     2018  01    Maths   95
John    Boston  USA    2019  01    Maths   95
Mark    London  UK     2019  01    Maths   83
John    Boston  USA    2018  01    Arts    90
Mark    London  UK     2018  01    Arts    95
John    Boston  USA    2019  01    Arts    95
Mark    London  UK     2019  01    Arts    83

Я хочу вывод как:

Student  City  Country  Year  Month  Maths_curr  Maths_prev  Arts_curr Arts_prev  
John     Boston USA     2019  01     95          90          95        90
John     Boston USA     2018  01     90          null        90        null
Mark     London UK      2019  01     83          95          83        95
Mark     London UK      2018  01     95          null        95        null 

Я думаю, мне нужно использовать функцию LAG, чтобы получить это... Я использовал этот код

select student,city,country,year,month,subject,marks as curr,
lag(marks,1)over(partition by student,city,country,subject order by year,month) as prev
from <table>
order by student,city,country,year,month

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

Student City    Countr  Year Month Subject  Curr  Prev
John    Boston  USA    2019  01    Maths    95    90
John    Boston  USA    2018  01    Maths    90    null
John    Boston  USA    2019  01    Arts     95    90
John    Boston  USA    2018  01    Arts     90    null
Mark    London  UK     2019  01    Maths    83    95
Mark    London  UK     2018  01    Maths    95    null
Mark    London  UK     2019  01    Arts     83    95
Mark    London  UK     2018  01    Arts     95    null

Можете ли вы помочь мне получить желаемый результат ... LEAD или LAG,правильные функции для использования в этом сценарии?Есть ли другой способ добиться этого в Redshift?

Любая помощь очень ценится.

Я также пробовал этот код ..

select student,city,country,year,month,subject,
case when substring(curr,1,1) = 'M' then cast(split_part(curr,' ',2) as integer) end as maths_curr,
case when substring(prev,1,1) = 'M' then cast(split_part(prev,' ',2) as integer) end as maths_prev,
case when substring(curr,1,1) = 'A' then cast(split_part(curr,' ',2) as integer) end as arts_curr,
case when substring(prev,1,1) = 'A' then cast(split_part(prev,' ',2) as integer) end as arts_prev
from
(select student,city,country,year,month,subject,
case when subject = 'MATHS' then 'M ' + cast(nvl(marks,0) as varchar)
     else 'A ' + cast(nvl(marks,0) as varchar)
     end as curr,
case when subject = 'MATHS' then 'M ' + cast(nvl(lag(marks,1)over (partition by student,city,country,subject order by year,mth),0) as varchar)
     else 'A ' + cast(nvl(lag(marks,1)over (partition by student,city,country,subject order by year,mth),0) as varchar)
     end as prev
from <table>
order by student,city,country,year,month)

В этом яполучить вывод в виде:

Student City    Country Year Month Subject  Maths_Curr  Maths_Prev   Arts_Curr   Arts_Prev
John    Boston  USA    2019  01    Maths    95          90           null        null
John    Boston  USA    2018  01    Maths    90          null         null        null
John    Boston  USA    2019  01    Arts     null        null         95          90
John    Boston  USA    2018  01    Arts     null        null         90          null
Mark    London  UK     2019  01    Maths    83          95           null        null
Mark    London  UK     2018  01    Maths    95          null         null        null
Mark    London  UK     2019  01    Arts     null        null         83          95
Mark    London  UK     2018  01    Arts     null        null         95          null

Не уверен, где именно я иду не так ... Нужны некоторые указания здесь ....

1 Ответ

0 голосов
/ 17 февраля 2019

Это должно сработать:

WITH base AS (
  SELECT *,
         CASE WHEN "Subject" = 'Maths' THEN "Marks" ELSE NULL END AS maths_current,
         CASE WHEN "Subject" = 'Arts' THEN "Marks" ELSE NULL END AS arts_current,
         CASE WHEN "Subject" = 'Maths' THEN LAG("Marks") OVER (PARTITION BY "Student","City","Country","Subject" ORDER BY "Year","Month") ELSE NULL END AS previous_math,
         CASE WHEN "Subject" = 'Arts' THEN LAG("Marks") OVER (PARTITION BY "Student","City","Country","Subject" ORDER BY "Year","Month") ELSE NULL END AS previous_arts
  FROM <table>
)

SELECT "Student",
       "City",
       "Country",
       "Year",
       "Month",
       MAX(maths_current) AS Maths_curr,
       MAX(previous_math) AS Maths_prev,
       MAX(arts_current) AS Arts_curr,
       MAX(previous_arts) AS Arts_prev
FROM base
GROUP BY 1,2,3,4,5
ORDER BY 1,2,3,4 DESC,5 DESC
...