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

e0uiprwp  于 2021-07-24  发布在  Java
关注(0)|答案(1)|浏览(237)

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

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 包含gps连接这些表 session_id ,就像这样:

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 . 我想确保对于每次旅行,记录都被选择到具有唯一时间戳的新表中(因此在上述情况下,只有一个记录应该被选择到新表中)。我用这把小提琴来说明这一点。
编辑
预期产量:

+-----------+------------+------------+------------+---------+------+
    |    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    |            |            |            |         |      |
    +-----------+------------+------------+------------+---------+------+
7z5jn7bk

7z5jn7bk1#

使用 DISTINCT ON :

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_id 也在新table上。
多亏了@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

这是一把小提琴。

相关问题