如何从长格式数据计算不规则间隔的百分比变化
How to calculate percent change from irregular intervals from long form data
我在tableP
中有数据
id bmi contact_date
1 25 01/01/2015
1 26 06/15/2015
2 20 01/01/2014
3 21 03/12/2014
3 22 04/15/2015
3 NULL 09/12/2015
3 23 12/10/2015
我想使用 SQL 做的是获取每个 ID 的两个最新值之间 BMI 的百分比变化(即每个 ID 一行)。如果没有两个值,那么我只希望有一个“0”。
id change
1 .04
2 0
3 .045
您可以使用row_number函数获取前两行的值并计算百分比变化。
select id,
coalesce((max(case when rn=1 then bmi end) - max(case when rn=2 then bmi end))
/(1.0*max(case when rn=2 then bmi end)),0) change
from (select t.*, row_number() over(partition by id order by contact_date desc) rn
from tablename t) x
group by id
您可以使用 OLAP 函数获取两个最近的值,然后它只是应用百分比计算:
SELECT id,
Coalesce((Cast(bmi AS DECIMAL(8,3)) / -- most recent bmi
Min(bmi) -- 2nd most recent bmi
Over (PARTITION BY id
ORDER BY contact_date DESC
ROWS BETWEEN 1 Following AND 1 Following)) - 1
, 0)
FROM tab t
WHERE bmi IS NOT NULL
QUALIFY -- this returns the most recent row
Row_Number()
Over (PARTITION BY id
ORDER BY contact_date DESC) = 1
这假设 bmi
(体重指数)永远不会为零,但在您的评论中您注意到 除以零 错误。您最好通过切换到 WHERE bmi > 0
(也排除 NULL)来删除零。
或者通过添加 NULLIF
将零更改为 NULL,如下所示:
Coalesce((Cast(bmi AS DECIMAL(8,3)) / -- most recent bmi
NullIf(Min(bmi) -- 2nd most recent bmi
Over (PARTITION BY id
ORDER BY contact_date DESC
ROWS BETWEEN 1 Following AND 1 Following),0)) - 1
, 0)
我在tableP
中有数据id bmi contact_date
1 25 01/01/2015
1 26 06/15/2015
2 20 01/01/2014
3 21 03/12/2014
3 22 04/15/2015
3 NULL 09/12/2015
3 23 12/10/2015
我想使用 SQL 做的是获取每个 ID 的两个最新值之间 BMI 的百分比变化(即每个 ID 一行)。如果没有两个值,那么我只希望有一个“0”。
id change
1 .04
2 0
3 .045
您可以使用row_number函数获取前两行的值并计算百分比变化。
select id,
coalesce((max(case when rn=1 then bmi end) - max(case when rn=2 then bmi end))
/(1.0*max(case when rn=2 then bmi end)),0) change
from (select t.*, row_number() over(partition by id order by contact_date desc) rn
from tablename t) x
group by id
您可以使用 OLAP 函数获取两个最近的值,然后它只是应用百分比计算:
SELECT id,
Coalesce((Cast(bmi AS DECIMAL(8,3)) / -- most recent bmi
Min(bmi) -- 2nd most recent bmi
Over (PARTITION BY id
ORDER BY contact_date DESC
ROWS BETWEEN 1 Following AND 1 Following)) - 1
, 0)
FROM tab t
WHERE bmi IS NOT NULL
QUALIFY -- this returns the most recent row
Row_Number()
Over (PARTITION BY id
ORDER BY contact_date DESC) = 1
这假设 bmi
(体重指数)永远不会为零,但在您的评论中您注意到 除以零 错误。您最好通过切换到 WHERE bmi > 0
(也排除 NULL)来删除零。
或者通过添加 NULLIF
将零更改为 NULL,如下所示:
Coalesce((Cast(bmi AS DECIMAL(8,3)) / -- most recent bmi
NullIf(Min(bmi) -- 2nd most recent bmi
Over (PARTITION BY id
ORDER BY contact_date DESC
ROWS BETWEEN 1 Following AND 1 Following),0)) - 1
, 0)