我是Postgresql的新手,我在循环中挣扎。我试图了解有关此主题的其他帖子,但我仍然被困住。
我有一个表“ Alltrips”,其中包含来自不同轨道(列行程)的GPS位置(X,Y)和时间戳。每个轨道都有一个ID。我想做的是在每组音轨上执行一个动作。
如果下一行具有相同的时间戳,我想将doublon_timestamp
列更新为True
。但是,如果轨道的最后一个时间戳与下一轨道的第一行具有相同的时间戳,则该行不能为True。
我想以这种方式进行操作,因为我打算重复使用此过程在每个轨道的GPS点之间绘制线,但不将轨道的最后一个点与下一个轨道的第一个点链接起来。
我尝试过这样的事情:
CREATE OR REPLACE FUNCTION public.testloop(
) RETURNS void
LANGUAGE 'plpgsql'
AS $BODY$
DECLARE
x alltrips.trips_id;
BEGIN
FOR x IN (SELECT * FROM public.alltrips)
LOOP
CASE WHEN alltrips.timedate = lead(alltrips.timedate)
OVER (ORDER BY alltrips.trips_id)
THEN UPDATE public.alltrips SET doublon_timestamp = true;
END CASE;
END LOOP;
END;
$BODY$;
但是不起作用。我知道我在DECLARE
部分遇到了麻烦。
我怎么了?
答案 0 :(得分:0)
看来,您可以使用带有派生表的单个UPDATE FROM
语句来实现您的要求,而不是使用函数和不必要的循环。
您可以尝试类似的操作(未经测试)
UPDATE alltrips t
SET doublon_timestamp = d.doublon_timestamp
FROM (SELECT trips_id,
CASE
WHEN timedate = LEAD(timedate)
OVER (
ORDER BY trips_id) THEN true
END AS doublon_timestamp from alltrips) d
WHERE d.trips_id = t.trips_id;
尽管您似乎建议在更新之前还需要检查其他标准,但是除非您在问题中提供一些样本数据,否则很难为您提供有效的解决方案,而该问题显然已经丢失
答案 1 :(得分:0)
我假设trips_id
是每个轨道trips
的索引,为此,我提出了以下示例表结构:
CREATE TABLE alltrips (
trips integer,
trips_id integer not null,
timedate timestamptz not null,
doublon_timestamp boolean not null default false,
primary key (trips, trips_id)
);
基于此,不需要已经指出的功能:
UPDATE alltrips AS u
SET doublon_timestamp = true
FROM (
SELECT trips, trips_id, timedate, lead(timedate) OVER (ORDER BY trips, trips_id) AS next
FROM alltrips
ORDER BY 1, 2
) AS t
WHERE
t.trips = u.trips
AND
t.trips_id = u.trips_id
AND
t.timedate = t.next
;
数据为http://sqlfiddle.com/#!17/925f5/1/0
的在线示例至少在我使用的结构正确的情况下,执行计划真的很整洁:
QUERY PLAN
-----------------------------------------------------------------------------------------------------------
Update on alltrips u (cost=0.30..114.66 rows=1 width=63)
-> Nested Loop (cost=0.30..114.66 rows=1 width=63)
-> Subquery Scan on t (cost=0.15..99.60 rows=9 width=48)
Filter: (t.timedate = t.next)
-> WindowAgg (cost=0.15..76.98 rows=1810 width=24)
-> Index Scan using alltrips_pkey on alltrips (cost=0.15..45.30 rows=1810 width=16)
-> Index Scan using alltrips_pkey on alltrips u (cost=0.15..1.67 rows=1 width=22)
Index Cond: ((trips = t.trips) AND (trips_id = t.trips_id))
(8 rows)
没有排序和合并联接总是一个好兆头...;)