ORACLE判断字段横向连续为空

褪色的丶旧时光 2021-08-20 14:43:33
idi1i2i3i4i5i6i7i8i9i10i11i12i13flag
256440.230.250.24    0.260.240.250.26 0.24 
256550.230.250.240.260.240.25 0.260.240.250.260.270.24 

 

如表格所示,如何判断一行内的数据连续4个点为空,将连续4个点为空的行,添加标记。

怎么进行判断,谢谢!

...全文
184 1 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
DarkAthena 2021-10-06
  • 打赏
  • 举报
回复

假定你的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;

17,140

社区成员

发帖
与我相关
我的任务
社区描述
Oracle开发相关技术讨论
社区管理员
  • 开发
  • Lucifer三思而后行
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧