Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 根据顺序(连续值)标记行_Sql_Postgresql_Window Functions - Fatal编程技术网

Sql 根据顺序(连续值)标记行

Sql 根据顺序(连续值)标记行,sql,postgresql,window-functions,Sql,Postgresql,Window Functions,这里的任务是根据行的顺序标记行 输入: 393403 "a" 0 1 393404 "b" 0 1 393404 "b" 2 1 393404 "b" 4 1 393404 "b" 5 1 393404 "c" 12 1 393404 "c" 14 1 393404 "c" 16 2 393404

这里的任务是根据行的顺序标记行

输入:

393403  "a" 0   1
393404  "b" 0   1
393404  "b" 2   1
393404  "b" 4   1
393404  "b" 5   1
393404  "c" 12  1
393404  "c" 14  1
393404  "c" 16  2
393404  "c" 21  1
393404  "c" 23  1
393404  "d" 28  1
393404  "d" 30  1
393404  "d" 32  2
393404  "d" 37  1
393404  "d" 39  1
393405  "e" 1   1
393405  "e" 4   1
393405  "e" 6   2
我想提取最后一列的序列为1 | 1 | 2的所有行。此外,第一列和第二列在该序列组中必须具有相同的值

在本例中,将是以下行:

393404  "c" 12  1
393404  "c" 14  1
393404  "c" 16  2


393404  "d" 28  1
393404  "d" 30  1
393404  "d" 32  2


393405  "e" 1   1
393405  "e" 4   1
393405  "e" 6   2
通过标记/摘录,我的意思是用1/2更新另一列

企图


我的第一次尝试是使用LAG函数,但如何从值2开始使用LAG?

这绝不是一个完整的答案

滞后/超前功能接受“偏移”参数:


我有,也许它会帮你。

这绝不是一个完整的答案

滞后/超前功能接受“偏移”参数:


我有,也许它会对你有所帮助。

前几天我在试验一个类似的问题,并想出了一些主意。在您的例子中,看起来您希望根据行的内容(第1列和第2列)以及具有相同第1列和第2列的相邻行的内容捕获行。这使得
LAG()
看起来是个好主意

重新考虑一下您的示例,我在前面或符合您条件的行中放置了一个
*
,并在右侧的一列中详细说明了顺序。我还给列起了化名,因为我对那些列是简单数字或“a”、“b”等的例子毫无用处。这是我的事,我会处理;-)

batch+team
分组和匹配似乎很普通,棘手的是
系列。“查找构成以
1-1-2
结尾的
系列的行

first
列似乎不是搜索的一部分,只是输出

这类似于我正在处理的一个问题。在我的例子中,这是事件的时间序列数据,其中序列是一组状态。比如“干净”、“准备”、“质量保证”和“存储”。但你的数字基本相同……我想


您是否想过构建该系列以使其成为一个可搜索的条件?可以通过按
batch
team
分组并在CTE中运行,或者通过在非规范化列中具体化该系列?如果没有,请查看标准扩展。它提供了大量的函数,操作员可以快速(可索引)完成这些函数路径搜索。这是我正在考虑的方向,但我没有足够的头脑去思考运算符,无法为您编写示例代码。如果这个想法听起来很有意思,希望其他人能提供更多帮助。

前几天我在试验一个类似的问题,并遇到了一些想法。在您的情况下,它是loo您希望根据行的内容(第1列和第2列)以及具有相同第1列和第2列的相邻行的内容捕获行。这使得
LAG()
看起来是个好主意

重新考虑一下你的例子,我在前面或符合你条件的行中放了一个
*
,并在右边的一列中说明了顺序。我还给列起了化名,因为我对那些列是简单数字或“a”、“b”等的例子毫无用处。这是我的事,我会处理;-)

batch+team
的分组和匹配似乎很普通,棘手的是
系列
“找到我的行,它们构成了一个以
1-1-2
结尾的
系列

first
列似乎不是搜索的一部分,只是输出

这类似于我正在解决的一个问题。在我的例子中,它是事件的时间序列数据,其中序列是一组状态。比如“清洁”、“准备”、“质量保证”和“储存”。但你们的数字基本上是一样的……我想


你有没有想过建立一个系列,使其成为一个可搜索的条件?实际上是通过按批
和团队
分组并在CTE中运行,还是通过在非规范化列中具体化系列?如果没有,请查看标准扩展。它提供了大量的函数和操作符来进行快速(可索引)路径搜索。这是我正在考虑的方向,但我没有足够的头脑来考虑操作符,无法为您编写示例代码。如果这个想法听起来很有意思,希望其他人能提供更多帮助。

谢谢大家花时间思考并帮助我。昨天我创建了基于光标的解决方案:

CREATE OR REPLACE PROCEDURE PUBLIC.TABELA4_INSERT(PROCESS_COUNT integer DEFAULT 50) LANGUAGE 'plpgsql' AS $BODY$
declare
    cur refcursor;
    trans_ record;
    what_prev integer = 0;
    raank_prev integer = 0;
    two boolean = false;
    two_id integer = 0;
    three boolean = false;
    three_id integer = 0;
    four boolean = false;
    four_id integer = 0;
BEGIN
open cur FOR
    with bl as
    (
        select tl.blocknumber
        from public.log tl left join
            tabela4 t4 on tl.blocknumber = t4.blocknumber
        where status_transferlogs = B'1' and date_transferlogs_parsed is not null
          and (
            status_swaplogs = B'1' and date_swaplogs_parsed is not null
              or
            status_swaplogs = B'0'
          )
        and tl.blocknumber > 393400
        group by tl.blocknumber
        order by tl.blocknumber
        limit process_count
    ), tl as
    (
        select tl.id, bl.blocknumber, tl.hash, tl.logindex, 1 what
        from public.tansferlogs tl join
            bl on tl.blocknumber = bl.blocknumber left join
            tabela4 t4 on tl.hash = t4.hash
        where t4.blocknumber is null
        group by tl.id, bl.blocknumber, tl.hash, tl.logindex
        union
        select tl.id, bl.blocknumber, tl.hash, tl.logindex, 2
        from public.swaplogs tl join
            bl on tl.blocknumber = bl.blocknumber left join
            tabela4 t4 on tl.hash = t4.hash
        where t4.blocknumber is null
        group by tl.id, bl.blocknumber, tl.hash, tl.logindex
    )
    select id, blocknumber, hash, logindex, what,
        DENSE_RANK() OVER (
           order by blocknumber, hash
        ) raank
    from tl
    order by blocknumber, hash, logindex desc;

truncate table films_recent;

loop

    fetch cur into trans_;
    exit when not found;
    
    INSERT INTO public.films_recent(blocknumber, hash, logindex, what, raank, id)
    VALUES (trans_.blocknumber, trans_.hash, trans_.logindex, trans_.what, trans_.raank, trans_.id);
    
    if raank_prev <> trans_.raank then
        two = false;
        two_id = 0;
        three = false;
        three_id = 0;
        four = false;
        four_id = 0;
        raank_prev = trans_.raank;
    end if;
        
    if trans_.what = 1 then
        if two and three then
            four = true;
            four_id = trans_.id;
        elseif two then
            three = true;
            three_id = trans_.id;
            four = false;
            four_id = 0;    
        end if;
    end if;
    if trans_.what = 2 then
        two = true;
        two_id = trans_.id;
        three = false;
        three_id = 0;
        four = false;
        four_id = 0;    
    
    end if;
    raise notice '%-%-%', two_id, three_id, four_id;
    if two and three and four then
        update films_recent
        set "check" = true
        where id = two_id and what = 2
         or what = 1 and id in (three_id, four_id);
        two = false;
        two_id = 0;
        three = false;
        three_id = 0;
        four = false;
        four_id = 0;        
    end if;
    
    
end loop;

close cur;

commit;

return;

END
$BODY$;

注意:结果按降序排列。

感谢大家花时间思考并帮助我解决这个问题。昨天我创建了基于光标的解决方案:

CREATE OR REPLACE PROCEDURE PUBLIC.TABELA4_INSERT(PROCESS_COUNT integer DEFAULT 50) LANGUAGE 'plpgsql' AS $BODY$
declare
    cur refcursor;
    trans_ record;
    what_prev integer = 0;
    raank_prev integer = 0;
    two boolean = false;
    two_id integer = 0;
    three boolean = false;
    three_id integer = 0;
    four boolean = false;
    four_id integer = 0;
BEGIN
open cur FOR
    with bl as
    (
        select tl.blocknumber
        from public.log tl left join
            tabela4 t4 on tl.blocknumber = t4.blocknumber
        where status_transferlogs = B'1' and date_transferlogs_parsed is not null
          and (
            status_swaplogs = B'1' and date_swaplogs_parsed is not null
              or
            status_swaplogs = B'0'
          )
        and tl.blocknumber > 393400
        group by tl.blocknumber
        order by tl.blocknumber
        limit process_count
    ), tl as
    (
        select tl.id, bl.blocknumber, tl.hash, tl.logindex, 1 what
        from public.tansferlogs tl join
            bl on tl.blocknumber = bl.blocknumber left join
            tabela4 t4 on tl.hash = t4.hash
        where t4.blocknumber is null
        group by tl.id, bl.blocknumber, tl.hash, tl.logindex
        union
        select tl.id, bl.blocknumber, tl.hash, tl.logindex, 2
        from public.swaplogs tl join
            bl on tl.blocknumber = bl.blocknumber left join
            tabela4 t4 on tl.hash = t4.hash
        where t4.blocknumber is null
        group by tl.id, bl.blocknumber, tl.hash, tl.logindex
    )
    select id, blocknumber, hash, logindex, what,
        DENSE_RANK() OVER (
           order by blocknumber, hash
        ) raank
    from tl
    order by blocknumber, hash, logindex desc;

truncate table films_recent;

loop

    fetch cur into trans_;
    exit when not found;
    
    INSERT INTO public.films_recent(blocknumber, hash, logindex, what, raank, id)
    VALUES (trans_.blocknumber, trans_.hash, trans_.logindex, trans_.what, trans_.raank, trans_.id);
    
    if raank_prev <> trans_.raank then
        two = false;
        two_id = 0;
        three = false;
        three_id = 0;
        four = false;
        four_id = 0;
        raank_prev = trans_.raank;
    end if;
        
    if trans_.what = 1 then
        if two and three then
            four = true;
            four_id = trans_.id;
        elseif two then
            three = true;
            three_id = trans_.id;
            four = false;
            four_id = 0;    
        end if;
    end if;
    if trans_.what = 2 then
        two = true;
        two_id = trans_.id;
        three = false;
        three_id = 0;
        four = false;
        four_id = 0;    
    
    end if;
    raise notice '%-%-%', two_id, three_id, four_id;
    if two and three and four then
        update films_recent
        set "check" = true
        where id = two_id and what = 2
         or what = 1 and id in (three_id, four_id);
        two = false;
        two_id = 0;
        three = false;
        three_id = 0;
        four = false;
        four_id = 0;        
    end if;
    
    
end loop;

close cur;

commit;

return;

END
$BODY$;

注:结果按降序排列。

您所说的“如何从值2开始滞后”是什么意思?据我所知,滞后将指分区中的前几行。您所说的“如何从值2开始滞后”是什么意思?据我所知,滞后将指分区中的前几行感谢您的努力,我对此表示感谢!将在一个循环(光标)中解决它谢谢你的努力,我很感激!将在一个循环(光标)中解决它。如果有一个功能,其中一个u可以直接连接到您要搜索的序列,那就太好了。加入你的主查询,就像你希望它适合的形状一样。如果有一个功能有一个u就可以加入你想要搜索的序列,那就好了。加入您的主查询,就像您希望它适合的形状一样。
393403  "a" 0   1   1   488594  
393404  "b" 39  1   2   488606  
393404  "b" 37  1   2   488605  
393404  "b" 32  2   2   2669079 true
393404  "b" 30  1   2   488604  true
393404  "b" 28  1   2   488603  true
393404  "c" 23  1   3   488602  
393404  "c" 21  1   3   488601  
393404  "c" 16  2   3   2669078 true
393404  "c" 14  1   3   488600  true
393404  "c" 12  1   3   488599  true
393404  "d" 5   1   4   488598  
393404  "d" 4   1   4   488597  
393404  "d" 2   1   4   488596