我的数据集在Teradata中如下所示:
╔═══════════╦══════════╦══════╗
║ studentid ║ date ║ days ║
╠═══════════╬══════════╬══════╣
║ 1000 ║ 2/1/2017 ║ 25 ║
║ 1000 ║ 3/8/2017 ║ 30 ║
║ 1000 ║ 4/4/2017 ║ 80 ║
║ 1000 ║ 5/1/2017 ║ 81 ║
║ 1001 ║ 1/1/2017 ║ 60 ║
║ 1001 ║ 2/1/2017 ║ 20 ║
║ 1001 ║ 4/1/2017 ║ 81 ║
╚═══════════╩══════════╩══════╝
我想有一个新的列(标志),如果最近两个日期都为80或81,则行上应显示1。如果不为0。
对于学生1001,所有行都应为0,因为最后两个日期不是80或81。它需要使用最后两个日期。即使1001的数字为81,倒数第二个日期的数字也为20,因此两者的标记都必须为0
所需的输出:
╔═══════════╦══════════╦══════╦══════╗
║ studentid ║ date ║ days ║ flag ║
╠═══════════╬══════════╬══════╬══════╣
║ 1000 ║ 2/1/2017 ║ 25 ║ 0 ║
║ 1000 ║ 3/8/2017 ║ 30 ║ 0 ║
║ 1000 ║ 4/4/2017 ║ 80 ║ 1 ║
║ 1000 ║ 5/1/2017 ║ 81 ║ 1 ║
║ 1001 ║ 1/1/2017 ║ 60 ║ 0 ║
║ 1001 ║ 2/1/2017 ║ 20 ║ 0 ║
║ 1001 ║ 4/1/2017 ║ 81 ║ 0 ║
╚═══════════╩══════════╩══════╩══════╝
答案 0 :(得分:0)
用row_number
分配行号,然后获取每个学生ID的最后两行的min
和max
值。之后,使用case
表达式检查条件以分配标志。
select studentid,dt,days
,case when rnum in (1,2) and max_days_latest_2 in (80,81) and min_days_latest_2 in (80,81) then 1 else 0 end as flag
from (select t.*
,max(case when rnum in (1,2) then days end) over(partition by studentid) as max_days_latest_2
,min(case when rnum in (1,2) then days end) over(partition by studentid) as min_days_latest_2
from (select t.*,row_number() over(partition by studentid order by dt desc) as rnum
from tbl t
) t
) t
答案 1 :(得分:0)
对于前两行,您可以应用简单的逻辑,这将在Explain中产生一个 STAT步骤
如果当前行是第一行:请检查此行和下一行是否都包含这些值之一
如果当前行是第二行:请检查此行和上一行是否都包含这些值之一
Segmentation fault Exited with code 139
如果您的Teradata版本不支持SELECT studentid, date_, Days,
CASE Row_Number()
Over (PARTITION BY studentid
ORDER BY date DESC)
WHEN 1
THEN CASE WHEN Days IN (80,81)
-- AND Min(Days) Over (PARTITION BY studentid ORDER BY date DESC ROWS BETWEEN 1 Following AND 1 Following) IN (80,81)
AND Lead(Days) Over (PARTITION BY studentid ORDER BY date DESC) IN (80,81)
THEN 1
ELSE 0
END
WHEN 2
THEN CASE WHEN Days IN (80,81)
-- AND Min(Days) Over (PARTITION BY studentid ORDER BY date DESC ROWS BETWEEN 1 Preceding AND 1 Preceding) IN (80,81)
AND Lag(Days) Over (PARTITION BY studentid ORDER BY date DESC) IN (80,81)
THEN 1
ELSE 0
END
ELSE 0
END AS flag
FROM tab
/ lead
,请使用lag
语法。
但是,如果您需要将此逻辑应用于> 2行,则需要一种更通用的方法:
min