PGSQL循环表

时间:2019-03-10 13:46:43

标签: postgresql

我是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部分遇到了麻烦。 我怎么了?

2 个答案:

答案 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)

没有排序和合并联接总是一个好兆头...;)