我有下表:
CREATE TABLE trajectory(
user_id int,
session_id int,
timestamp timestamp with time zone,
lat double precision,
lon double precision
);
INSERT INTO trajectory(user_id, session_id, timestamp, lat, lon) VALUES
(1, 25304,'2008-10-23 02:53:04+01', 39.984702, 116.318417),
(1, 25304, '2008-10-23 02:53:10+01', 39.984683, 116.31845),
(1, 25304, '2008-10-23 02:53:15+01', 39.984686, 116.318417),
(1, 25304, '2008-10-23 02:53:20+01', 39.984688, 116.318385),
(1, 20959,'2008-10-24 02:09:59+01', 40.008304, 116.319876),
(1, 20959,'2008-10-24 02:10:04+01', 40.008413, 116.319962),
(1, 20959,'2008-10-24 02:10:14+01', 40.007171, 116.319458),
(2, 55305, '2008-10-23 05:53:05+01', 39.984094, 116.319236),
(2, 55305, '2008-10-23 05:53:11+01', 39.984198, 116.319322),
(2, 55305, '2008-10-23 05:53:21+01', 39.984224, 116.319402),
(2, 34104, '2008-10-23 23:41:04+01', 40.013867, 116.306473),
(2, 34104, '2008-10-23 23:41:16+01', 40.013907, 116.306488);
问题:
我想在user_id
和session_id
列的基础上向该表添加一列trip_id
,这样当用户的会话id更改时,我知道用户正在进行新的旅行,因此我将该id添加到新的trip
列。
所需输出:
user_id |session_id |timestamp | lat | lon | trip_id
--------|------------|-----------------------|--------------|-----------|-----------
1 | 25304 |2008-10-23 02:53:04+01 | 39.984702 |116.318417 | 1
1 | 25304 |2008-10-23 02:53:10+01 | 39.984683 |116.31845 | 1
1 | 25304 |2008-10-23 02:53:15+01 | 39.984686 |116.318417 | 1
1 | 25304 |2008-10-23 02:53:20+01 | 39.984688 |116.318385 | 1
1 | 20959 |2008-10-24 02:09:59+01 |40.008304 |116.319876 | 2
1 | 20959 |2008-10-24 02:10:04+01 |40.008413 |116.319962 | 2
1 | 20959 |2008-10-24 02:10:14+01 |40.007171 |116.319458 | 2
2 | 55305 |2008-10-23 05:53:05+01 |39.984094 |116.319236 | 1
2 | 55305 |2008-10-23 05:53:11+01 |39.984198 |116.319322 | 1
2 | 55305 |2008-10-23 05:53:21+01 |39.984224 |116.319402 | 1
2 | 34104 |2008-10-23 23:41:04+01 |40.013867 |116.306473 | 2
2 | 34104 |2008-10-23 23:41:16+01 |40.013907 |116.306488 | 2
How can I do this?
编辑
感谢这些伟大的答案,但所有收到的答案都是检索表值,它们不会修改表。另外,我添加了最初忽略的timestamp
列,以为这样可以简化我的问题。
3条答案
按热度按时间bkhjykvo1#
我们可以用缺口和孤岛技术来解决这个问题。假设你有一个列来排序你的数据集,比如
ordering_id
:其思想是将同一用户的“前一个”会话ID与
lag
一起带入,然后将其与当前行上的值进行比较;然后,我们可以计算它改变了多少次,这定义了行程ID。| 用户id|会话ID|后来|隆|订购ID|滞后会话ID|跳闸标识|
| - -----|- -----|- -----|- -----|- -----|- -----|- -----|
| 一个|25304| 39.984702| 116.318417|一个|联系我们|一个|
| 一个|25304| 39.984683| 116.31845| 2| 25304|一个|
| 一个|25304| 39.984686| 116.318417| 3| 25304|一个|
| 一个|25304| 39.984688| 116.318385| 4| 25304|一个|
| 一个|20959| 40.008304| 116.319876| 5个|25304| 2|
| 一个|20959| 40.008413| 116.319962|六|20959| 2|
| 一个|20959| 40.007171| 116.319458|七个|20959| 2|
| 2|五五三零五|39.984094| 116.319236|八|联系我们|一个|
| 2|五五三零五|39.984198| 116.319322|九个|五五三零五|一个|
| 2|五五三零五|39.984224| 116.319402|十个|五五三零五|一个|
| 2| 34104| 40.013867| 116.306473|十一|五五三零五|2|
| 2| 34104| 40.013907| 116.306488|十二岁|34104| 2|
fiddle
kdfy810k2#
还有一种办法是:
DENSE RANK
。如果您没有任何排序字段,您可以使用“ctid”来实现此目的:它是一个存储表中每行的物理位置的字段。否则使用timestamp字段代替“ctid"。
输出:
| 用户id|会话ID|后来|隆|跳闸标识|
| - -----|- -----|- -----|- -----|- -----|
| 一个|25304| 39.984702| 116.318417|一个|
| 一个|25304| 39.984683| 116.31845|一个|
| 一个|25304| 39.984686| 116.318417|一个|
| 一个|25304| 39.984688| 116.318385|一个|
| 一个|20959| 40.008304| 116.319876| 2|
| 一个|20959| 40.008413| 116.319962| 2|
| 一个|20959| 40.007171| 116.319458| 2|
| 2|五五三零五|39.984094| 116.319236|一个|
| 2|五五三零五|39.984198| 116.319322|一个|
| 2|五五三零五|39.984224| 116.319402|一个|
| 2| 34104| 40.013867| 116.306473| 2|
| 2| 34104| 40.013907| 116.306488| 2|
查看演示here。
vhipe2zx3#
这可以通过使用窗口函数
lag()
检索前一行并确定它是否已更改,然后使用窗口函数sum()
检索trip_id
来实现:假设user_id/timestamp是唯一的,则更新可以是:
结果:
| 用户id|会话ID|时间戳|后来|隆|跳闸标识|
| - -----|- -----|- -----|- -----|- -----|- -----|
| 一个|25304| 2008-10-23 02:53:04+01| 39.984702| 116.318417|一个|
| 一个|25304| 2008-10-23 02:53:10+01| 39.984683| 116.31845|一个|
| 一个|25304| 2008-10-23 02:53:15+01| 39.984686| 116.318417|一个|
| 一个|25304| 2008-10-23 02:53:20+01| 39.984688| 116.318385|一个|
| 一个|20959| 2008-10-24 02:09:59+01| 40.008304| 116.319876| 2|
| 一个|20959| 2008-10-24 02:10:04+01| 40.008413| 116.319962| 2|
| 一个|20959| 2008-10-24 02:10:14+01| 40.007171| 116.319458| 2|
| 2|五五三零五|2008-10-23 05:53:05+01| 39.984094| 116.319236|一个|
| 2|五五三零五|2008-10-23 05:53:11+01| 39.984198| 116.319322|一个|
| 2|五五三零五|2008-10-23 05:53:21+01| 39.984224| 116.319402|一个|
| 2| 34104| 2008-10-23 23:41:04+01| 40.013867| 116.306473| 2|
| 2| 34104| 2008-10-23 23:41:16+01| 40.013907| 116.306488| 2|
Demo here