PostgreSQL:为所有行创建具有唯一时间戳的表

PostgreSQL:为所有行创建具有唯一时间戳的表,sql,postgresql,join,crud,Sql,Postgresql,Join,Crud,我在如下表格中记录了用户的行程,包括开始/结束位置和时间: CREATE TABLE trips(id integer, start_timestamp timestamp with time zone, session_id integer, start_lat double precision, start_lon double precision, end_lat double precision,

我在如下表格中记录了用户的行程,包括开始/结束位置和时间:

CREATE TABLE trips(id integer, start_timestamp timestamp with time zone, 
                   session_id integer, start_lat double precision,
                   start_lon double precision, end_lat double precision, 
                   end_lon double precision, mode integer);

INSERT INTO trips (id, start_timestamp, session_id, start_lat,start_lon,end_lat,end_lon,mode)
VALUES (563097015,'2017-05-20 17:47:12+01', 128618, 41.1783308,-8.5949878, 41.1784478, -8.5948463, 0),
 (563097013, '2017-05-20 17:45:29+01', 128618, 41.1781344, -8.5951169, 41.1782919, -8.5950689,  0),
 (563097011, '2017-05-20 17:43:41+01', 128618, 41.1781196, -8.5954075, 41.1782139, -8.5950689,  0),
 (563097009, '2017-05-20 17:41:48+01', 128618, 41.1782497,  -8.595197, 41.1781101, -8.5954124,  0),
 (563097003, '2017-05-20 17:10:29+01', 128618, 41.1832512, -8.6081606, 41.1782561, -8.5950259,  0)
第二个表中是所有行程的原始gps轨迹记录,类似于:

CREATE TABLE gps_traces (session_id integer, seconds integer, lat double precision,
                         lon double precision, speed double precision);

INSERT INTO gps_traces (session_id, seconds , lat , lon , speed )
VALUES (128618,1495296443,41.1844471,-8.6065158,1.35148),
     (128618,1495296444,41.1844482,-8.6065303,1.28004),
     (128618,1495296445,41.1844572,-8.6065503,1.46086),
     (128618,1495296446,41.1844541,-8.6065691,1.23),
     (128618,1495296446,41.1844589,-8.6065861, 1.22919),
     (128618,1495296447,41.1844587, -8.6066043, 1.30188),
     (128618, 1495296448, 41.1844604, -8.6066261, 1.43126),
     (128618, 1495296449, 41.184471, -8.6066412, 1.55003),
     (128618,1495296450, 41.1844715, -8.6066572, 1.29062),
     (128618,1495296450, 41.1844707, -8.6066736,  1.3618)
由此,我想创建一个新表
mytable
,其中包含在
session\u id
上连接这些表的GPS,如下所示:

CREATE TABLE mytable AS SELECT id, seconds, lat, lon, speed, mode
FROM trips t
JOIN gps_traces g
ON t.session_id=g.session_id
但是,在新表中,我希望确保对于在一次行程中在同一unix时间戳中记录两次的行,只在我的新表中选择了only。例如,在这种情况下:

SELECT * FROM mytable WHERE id = 563097003; 
+-----------+------------+------------+------------+---------+------+
|    id     |  seconds   |    lat     |    lon     |  speed  | mode |
+-----------+------------+------------+------------+---------+------+
| 563097003 | 1495296443 | 41.1844471 | -8.6065158 | 1.35148 |    0 |
| 563097003 | 1495296444 | 41.1844482 | -8.6065303 | 1.28004 |    0 |
| 563097003 | 1495296445 | 41.1844572 | -8.6065503 | 1.46086 |    0 |
| 563097003 | 1495296446 | 41.1844541 | -8.6065691 | 1.23    |    0 |
| 563097003 | 1495296446 | 41.1844589 | -8.6065861 | 1.22919 |    0 |
| 563097003 | 1495296447 | 41.1844587 | -8.6066043 | 1.30188 |    0 |
| 563097003 | 1495296448 | 41.1844604 | -8.6066261 | 1.43126 |    0 |
| 563097003 | 1495296449 | 41.184471  | -8.6066412 | 1.55003 |    0 |
| 563097003 | 1495296450 | 41.1844715 | -8.6066572 | 1.29062 |    0 |
| 563097003 | 1495296450 | 41.1844707 | -8.6066736 | 1.3618  |    0 |
| 10 rows   |            |            |            |         |      |
+-----------+------------+------------+------------+---------+------+
seconds
是Unix时间戳。如图所示,我们可以看到在
1495296446
1495296450
处有超过1个唯一时间戳计数的行。我希望确保对于每次旅行,都会将记录选择到具有唯一时间戳的新表中(因此在上述情况下,只应将一条记录选择到新表中)。我用这个例子来说明这一点

编辑

预期产出:

    +-----------+------------+------------+------------+---------+------+
    |    id     |  seconds   |    lat     |    lon     |  speed  | mode |
    +-----------+------------+------------+------------+---------+------+
    | 563097003 | 1495296443 | 41.1844471 | -8.6065158 | 1.35148 |    0 |
    | 563097003 | 1495296444 | 41.1844482 | -8.6065303 | 1.28004 |    0 |
    | 563097003 | 1495296445 | 41.1844572 | -8.6065503 | 1.46086 |    0 |
    | 563097003 | 1495296446 | 41.1844541 | -8.6065691 | 1.23    |    0 |
    | 563097003 | 1495296447 | 41.1844587 | -8.6066043 | 1.30188 |    0 |
    | 563097003 | 1495296448 | 41.1844604 | -8.6066261 | 1.43126 |    0 |
    | 563097003 | 1495296449 | 41.184471  | -8.6066412 | 1.55003 |    0 |
    | 563097003 | 1495296450 | 41.1844715 | -8.6066572 | 1.29062 |    0 |
    | 8 rows    |            |            |            |         |      |
    +-----------+------------+------------+------------+---------+------+

在上使用不同的

CREATE TABLE mytable AS
    SELECT DISTINCT ON (t.session_id, seconds) id, seconds, lat, lon, speed, mode
    FROM trips t JOIN
         gps_traces g
         ON t.session_id = g.session_id
    ORDER BY t.session_id, seconds;
注意:我希望您在新表中也包括
session\u id

多亏了@Abelisto,结果证明对这个答案的以下修改是按预期进行的

CREATE TABLE mytable AS SELECT DISTINCT ON (id, seconds)id, 
 seconds, lat, lon, speed, mode
FROM trips t
JOIN gps_traces g
ON t.session_id=g.session_id
ORDER BY id, seconds

是一个DBFIDLE。

错误:
列引用“session\u id”不明确第2行:选择DISTINCT ON(session\u id,seconds)id,seconds,la.
@super\u ask。这应该是合格的。但是这只给出了两行而不是问题中的所有行,在
秒内没有重复
奇怪的是,它在
selectdistinct on(..)
b上起作用,但在
上不作为selectdistinct on(..)
创建表,因此,例如,
id=56309703
只返回了两行。此id应该有八行。“只应选择一条记录”此处的主要问题:到底是哪一条?@Abelisto例如,在预期答案表中,选择了时间戳
1495296446
1495296450
的第一条记录。在新表中,
id=56309703
现在有8行,而不是10行。我的意思是:那些具有重复的
seconds
值的行只因
lat/lon/speed
而不同。你如何决定哪一个应该出现在最终数据中?有一个固定的戈登的答案:祝你好运!)注意,没有任何重要排序的“第一行”表示“随机”。因此,您可能需要将
g.ctid desc
添加到
order by
子句中,以获取最后插入的行。