转换表以使记录更整齐

时间:2019-11-15 08:05:18

标签: python sql oracle plsql

情况(现实生活中的情况)是:

我有一个带有“日志”记录的表,为简单起见,我们假设只有 NAME,TIME,STATE 列(实际上只有很少的列)。有cca 1百万行,其中有 100个名称(计算机)和cca 10个状态(生产,闲置,自动化,维护。)。 ) 可以解释为:*在t0时computer1处于空闲状态,在t1时computer1处于生产状态... ,依此类推。

  

请问您的帮助,以将空闲状态替换为之前的状态,如果连续闲置次数少于5个。其他每个状态都会重置“空闲计数器”,如果有5个以上的空闲,则保持第6个及以后的空闲状态。

最好在示例中对此进行描述,因此对于下面的灰色,我们假设:

  • STATE列是内联编写的
  • 只有一个名字
  • 字母ABCD...描述的
  • 状态,I是空闲状态
  • 按时间排序的数据,最旧的
STATE column I HAVE: AABBCIICAABAIIIIIIIIIAAAIIIBIIAACC...
STATE column I NEED: AABBCCCCAABAAAAAAIIIIAAAAAABBBAACC...

您可以轻松地看到,只有5个空闲状态被先前的状态“覆盖”。

已确定对这些短的空闲周期进行了误肯定评估,应予以消除(较长的周期被延迟,如代码示例中所示)。我有cca 24 1M记录表,需要“重新计算”为这种新格式。 我不是要寻找简单的选择,我需要执行更新,因此表格将保持这种新格式,以后可以与之一起使用直到现在。

我不是一个完整的sql初学者,到目前为止,我怀疑这种方式是通过将 OVER 子句与 PARTITION PRECEDING 和< em>关注,但这是我遇到的困难。

如果需要,我可以使用* CREATE TABLE AS SELECT ... *并删除旧表的方法。 我也很精通python,但是我看不到有效地获取,处理和运行这么多更新的方法。

非常感谢您的建议。

1 个答案:

答案 0 :(得分:1)

这对您有帮助吗?(我使用计数器而不是时间戳):

    create table tsovf (id varchar2(10), rn number, cond varchar2(1));

    insert into tsovf 
    select 'comp1', rownum, substr('AABBCIICAABAIIIIIIIIIAAAIIIBIIAACC',rownum,1)
    from dual
    connect by level<length('AABBCIICAABAIIIIIIIIIAAAIIIBIIAACC');

    insert into tsovf 
    select 'comp2', rownum, substr('AABBCIICAABAIIIIIIIIIAAAIIIBIIAACC',rownum,1)
    from dual
    connect by level<length('AABBCIICAABAIIIIIIIIIAAAIIIBIIAACC');

    with fq as (select id, rn, cond, 
    lag( cond,1) over (partition by id order by rn) prv1,
    lag( cond,2) over (partition by id order by rn) prv2,
    lag( cond,3) over (partition by id order by rn) prv3,
    lag( cond,4) over (partition by id order by rn) prv4,
    lag( cond,5) over (partition by id order by rn) prv5
    from tsovf),
    sq as (
    select id,rn, 
    case 
    when cond='I' and prv1!='I' then prv1
    when cond='I' and prv2!='I' then prv2
    when cond='I' and prv3!='I' then prv3
    when cond='I' and prv4!='I' then prv4
    when cond='I' and prv5!='I' then prv5
    else cond
    end cond
    from fq)
    select * 
    from sq
    order by id,rn;

输出为:

    comp1   1   A
    comp1   2   A
    comp1   3   B
    comp1   4   B
    comp1   5   C
    comp1   6   C
    comp1   7   C
    comp1   8   C
    comp1   9   A
    comp1   10  A
    comp1   11  B
    comp1   12  A
    comp1   13  A
    comp1   14  A
    comp1   15  A
    comp1   16  A
    comp1   17  A
    comp1   18  I
    comp1   19  I
    comp1   20  I
    comp1   21  I
    comp1   22  A
    comp1   23  A
    comp1   24  A
    comp1   25  A
    comp1   26  A
    comp1   27  A
    comp1   28  B
    comp1   29  B
    comp1   30  B
    comp1   31  A
    comp1   32  A
    comp1   33  C
    comp2   1   A
    comp2   2   A
    comp2   3   B
    comp2   4   B
    comp2   5   C
    comp2   6   C
    comp2   7   C
    comp2   8   C
    comp2   9   A
    comp2   10  A
    comp2   11  B
    comp2   12  A
    comp2   13  A
    comp2   14  A
    comp2   15  A
    comp2   16  A
    comp2   17  A
    comp2   18  I
    comp2   19  I
    comp2   20  I
    comp2   21  I
    comp2   22  A
    comp2   23  A
    comp2   24  A
    comp2   25  A
    comp2   26  A
    comp2   27  A
    comp2   28  B
    comp2   29  B
    comp2   30  B
    comp2   31  A
    comp2   32  A
    comp2   33  C