17,140
社区成员




id | i1 | i2 | i3 | i4 | i5 | i6 | i7 | i8 | i9 | i10 | i11 | i12 | i13 | flag |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
25644 | 0.23 | 0.25 | 0.24 | 0.26 | 0.24 | 0.25 | 0.26 | 0.24 | ||||||
25655 | 0.23 | 0.25 | 0.24 | 0.26 | 0.24 | 0.25 | 0.26 | 0.24 | 0.25 | 0.26 | 0.27 | 0.24 |
如表格所示,如何判断一行内的数据连续4个点为空,将连续4个点为空的行,添加标记。
怎么进行判断,谢谢!
假定你的id是唯一键,要判断的字段名称都是i加连续数字,另外也不确定是否存在为0的值,
方案一:
那么最不用思考的做法就是你的提问本身,即一行一行找,然后每四个连续字段判断是否为空,这里就涉及到两个循环了
DECLARE
I NUMBER;
L_SQL VARCHAR2(4000);
begin
for rec in (select id from test_t) loop
FOR I IN 1 .. 10 LOOP
L_SQL := 'update test_t set flag=1 where id=' || to_char(rec.id) ||
' and coalesce(' || 'i' || to_char(i) || ',' || 'i' ||
to_char(i + 1) || ',' || 'i' || to_char(i + 2) || ',' || 'i' ||
to_char(i + 3) || ') is null';
execute immediate l_sql;
end loop;
end loop;
end;
/
其实代码还能优化,比如某一行已经更新过了就直接跳到下一行,减少无效执行;
如果你要判断的字段名称无规律,那么就结合dba_tab_cols视图来生成动态sql
方案二:
你可以把这些字段名通过unpivot函数转到一列里去,让这些数值都变成一列,然后使用开窗函数count最近四行的值,对这个值进行判断即可(空值不会被count),这样就不用写过程,一个sql就能完成你的要求,你有兴趣可以自己尝试写下
方案三:
另外还有个比较脑洞而且超级简单的做法,大家都知道,空没有长度,几个空拼在一起还是一个空 ,如果使用NVL把空值变成你这个表中不存在的一个值,比如字母"A",然后把这些字段全部用管道符拼成一个字符串,那么就只需要判断这个字符串中是否存在 “AAAA”了,存在的那行就是要标记的那行
update test_t
set flag = 1
where INSTR(nvl(to_char(i1), 'A') || nvl(to_char(i2), 'A') ||
nvl(to_char(i3), 'A') || nvl(to_char(i4), 'A') ||
nvl(to_char(i5), 'A') || nvl(to_char(i6), 'A') ||
nvl(to_char(i7), 'A') || nvl(to_char(i8), 'A') ||
nvl(to_char(i9), 'A') || nvl(to_char(i10), 'A') ||
nvl(to_char(i11), 'A') || nvl(to_char(i12), 'A') ||
nvl(to_char(i13), 'A'),
'AAAA') > 0;