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