如何在自连接条件下创建 if then 逻辑?

How do I create if then logic in self-join condition?

我有一个数据集,其中包含学生姓名、技能以及他们每年在这些技能上的分数。 我想要一个查询来找出哪个学生在任何技能上的增长最快?成长周期可以是1-3年(部分年份有缺失值)

因此,如果学生和技能有 2000 年、2001 年和 2002 年的记录,要计算 2002 年的增长,我们需要查看 2001 年。 如果学生和技能只有 2000 年和 2002 年的记录,要计算增长,我们可以查看 2000 年(仅当 2001 年不存在时)。

我想做一个自连接来创建一个比较分数的基础。试图在此连接条件下创建生长期逻辑但卡住了。

SELECT q1.STUDENT, q1.SKILL, q1.YEAR, q2.YEAR, q1.SCORE, q2.SCORE
FROM Table q1
INNER JOIN Table q2
ON q1.STUDENT = q2.STUDENT AND q1.SKILL = q2.SKILL AND ... 
-- This is where I get stuck

(q1.YEAR = q2.YEAR - 1)  -- Case 1
(q1.YEAR <> q2.YEAR - 1) AND (q1.YEAR = q2.YEAR - 2) -- Case 2
(q1.YEAR <> q2.YEAR - 1) AND (q1.YEAR <> q2.YEAR - 2) AND (q1.YEAR = q2.YEAR - 3) -- Case

我知道这些案件现在有点合并了?如何以 IF 逻辑方式使它们 运行?

示例数据:

它们应该是三个不同的查询联合在一起吗?

您可以使用lag window函数来计算增长而不是自连接。

with t as
(
 select 
   student, skill, 
   case when year-lag(year) over w <= 3 then score-lag(score, 1) over w end as growth
 from _table
 window w as (partition by student, skill order by year)
)
select distinct on (skill) student, skill, growth
from t
order by skill, growth desc nulls last;

t CTE growth 中,(学生,技能)记录组中的每个第一年都会 null