我有一个名为myTable的活动表,数据如下所示:
CREATE TABLE myTable
(
userid text,
webid text,
"ts" timestamp
);
INSERT INTO myTable
("userid", "webid", "ts")
VALUES ('1', 'A', '34', '2023-01-31 16:34:49.000'),
('2', 'A', '73', '2023-01-31 16:34:50.000'),
('3', 'A', '97', '2023-01-31 16:34:58.000'),
('4', 'A', '17', '2023-01-31 17:35:02.000'),
('5', 'A', '17', '2023-01-31 17:35:07.000'),
('6', 'A', '17', '2023-01-31 17:35:18.000'),
('7', 'A', '17', '2023-01-31 17:35:30.000'),
('8', 'A', '1', '2023-01-31 17:35:37.000'),
('9', 'A', '1', '2023-01-31 17:35:38.000'),
('10', 'A', '77', '2023-01-31 17:35:41.000'),
('11', 'A', '77', '2023-01-31 17:35:42.000'),
('12', 'A', '15', '2023-01-31 17:35:42.000'),
('13', 'A', '44', '2023-01-31 17:35:42.000'),
('14', 'A', '1', '2023-01-31 17:35:42.000'),
('15', 'A', '77', '2023-01-31 17:35:45.000'),
('16', 'A', '44', '2023-01-31 17:35:45.000'),
('17', 'A', '1', '2023-01-31 17:37:10.000'),
('18', 'A', '1', '2023-01-31 17:37:12.000'),
('19', 'A', '77', '2023-01-31 17:37:14.000'),
('20', 'A', '77', '2023-01-31 17:52:14.000'),
('21', 'A', '77', '2023-01-31 18:12:14.000'),
('22', 'A', '77', '2023-01-31 18:45:14.000'),
('23', 'A', '77', '2023-01-31 18:55:15.000'),
('1', 'B', '33', '2023-01-31 06:37:15.000'),
('2', 'B', '56', '2023-01-31 06:40:15.000')
;
| 劳伊德|用户识别码|网络标识符|ts|
| - ------|- ------|- ------|- ------|
| 1个|A类|三十四|2023年1月31日16时34分49秒|
| 第二章|A类|七十三|2023年1月31日16时34分50秒|
| 三个|A类|九十七|2023年1月31日16时34分58秒|
| 四个|A类|十七|2023年1月31日17时35分02秒|
| 五个|A类|十七|2023年1月31日17时35分07秒|
| 六个|A类|十七|2023年1月31日17时35分18秒|
| 七|A类|十七|2023年1月31日17时35分30秒|
| 八个|A类|1个|2023年1月31日17时35分37秒|
| 九|A类|1个|2023年1月31日17时35分38秒|
| 十个|A类|七十七|2023年1月31日17时35分41秒|
| 十一|A类|七十七|2023年1月31日17时35分42秒|
| 十二|A类|十五|2023年1月31日17时35分42秒|
| 十三|A类|四十四|2023年1月31日17时35分42秒|
| 十四|A类|1个|2023年1月31日17时35分42秒|
| 十五|A类|七十七|2023年1月31日17时35分45秒|
| 十六|A类|四十四|2023年1月31日17时35分45秒|
| 十七|A类|1个|2023年1月31日17时37分10秒|
| 十八|A类|1个|2023年1月31日17时37分12秒|
| 十九|A类|七十七|2023年1月31日17时37分14秒|
| 二十个|A类|七十七|2023年1月31日17时52分14秒|
| 二十一|A类|七十七|2023年1月31日18时12分14秒|
| 二十二|A类|七十七|2023年1月31日18时45分14秒|
| 二十三|A类|七十七|2023年1月31日18时55分15秒|
| 1个|B|三十三|2023年1月31日06:37:15|
| 第二章|B|五十六|2023年1月31日06时40分15秒|
我要返回的输出如下:
| 劳伊德|用户识别码|网络标识符|会话标识|ts|第一个_ts|
| - ------|- ------|- ------|- ------|- ------|- ------|
| 1个|A类|三十四|1个|2023年1月31日16时34分49秒|2023年1月31日16时34分49秒|
| 第二章|A类|七十三|第二章|2023年1月31日16时34分50秒|2023年1月31日16时34分50秒|
| 三个|A类|九十七|三个|2023年1月31日16时34分58秒|2023年1月31日16时34分58秒|
| 四个|A类|十七|四个|2023年1月31日17时35分02秒|2023年1月31日17时35分02秒|
| 五个|A类|十七|四个|2023年1月31日17时35分07秒|2023年1月31日17时35分02秒|
| 六个|A类|十七|四个|2023年1月31日17时35分18秒|2023年1月31日17时35分02秒|
| 七|A类|十七|四个|2023年1月31日17时35分30秒|2023年1月31日17时35分02秒|
| 八个|A类|1个|五个|2023年1月31日17时35分37秒|2023年1月31日17时35分37秒|
| 九|A类|1个|五个|2023年1月31日17时35分38秒|2023年1月31日17时35分37秒|
| 十个|A类|七十七|六个|2023年1月31日17时35分41秒|2023年1月31日17时35分41秒|
| 十一|A类|七十七|六个|2023年1月31日17时35分42秒|2023年1月31日17时35分42秒|
| 十二|A类|十五|七|2023年1月31日17时35分42秒|2023年1月31日17时35分42秒|
| 十三|A类|四十四|八个|2023年1月31日17时35分42秒|2023年1月31日17时35分42秒|
| 十四|A类|1个|九|2023年1月31日17时35分42秒|2023年1月31日17时35分42秒|
| 十五|A类|七十七|十个|2023年1月31日17时35分45秒|2023年1月31日17时35分45秒|
| 十六|A类|四十四|十一|2023年1月31日17时35分45秒|2023年1月31日17时35分45秒|
| 十七|A类|1个|十二|2023年1月31日17时37分10秒|2023年1月31日17时37分10秒|
| 十八|A类|1个|十二|2023年1月31日17时37分12秒|2023年1月31日17时37分10秒|
| 十九|A类|七十七|十三|2023年1月31日17时37分14秒|2023年1月31日17时37分14秒|
| 二十个|A类|七十七|十三|2023年1月31日17时52分14秒|2023年1月31日17时37分14秒|
| 二十一|A类|七十七|十三|2023年1月31日18时12分14秒|2023年1月31日17时37分14秒|
| 二十二|A类|七十七|十四|2023年1月31日18时45分14秒|2023年1月31日18时45分14秒|
| 二十三|A类|七十七|十四|2023年1月31日18时55分15秒|2023年1月31日18时45分14秒|
| 1个|B|三十三|1个|2023年1月31日06:37:15|2023年1月31日06:37:15|
| 第二章|B|五十六|第二章|2023年1月31日06时40分15秒|2023年1月31日06时40分15秒|
first_ts表示第一个时间戳,first_ts的逻辑是如果用户ID在连续的时间戳访问同一个webID,并且每个时间戳的间隔福尔斯30分钟以内,则将这些访问记录为一个会话,例如,第4、5、6、7行,每个时间间隔都小于30分钟,则其first_ts为第一个事件的时间戳,即2023-01-31 17:35:02。
如果用户ID访问一个webid跳转到另一个webid返回到第一个webid,则first_ts刷新到当前时间戳,如第8、9、10、11、12、13、14、15、16、17、18行,用户ID A先访问webid=1,然后跳转到webid= 77、15、44,返回webid=1后,再到第12行。行13和行14应当被记录为具有当前first_ts的新会话。
如果一个userid在连续的时间戳访问一个webid,并且有一个时间戳间隔大于30分钟,也会中断会话并刷新first_ts,例如第19、20、21、22、23行,第21行和第22行之间的时间间隔超过30分钟,那么对于第22行和第23行,它们的first_ts被刷新为当前时间戳,并且它们将成为新的会话。
我在这里分享我的脚本,该脚本包含了视图的rowid,看起来它返回了正确的first_ts,但是session_id是错误的。
SQL版本:
create temp table lags as
select *, lag(webid,1,webid) over(partition by userid order by ts) lag_webid,
lag(ts,1,ts) over(partition by userid order by ts) lag_ts
from mytable;
create temp table is_sessions as
select *,
case when webid!=lag_webid or abs(datediff(minutes,ts,lag_ts)) > 30 then 1
else 0
end as is_session
from lags;
create temp table sessions as
select *,
sum(is_session) over(partition by userid order by ts)+1 as session_id
from is_sessions;
create temp table sessions_ts as
select *,
min(ts) over(partition by userid, session_id order by ts) as first_ts
from sessions;
等效PostgreSQL版本:
select rowid, userid, webid, session_id, ts, min(ts) over(partition by userid, session_id order by ts) first_ts
from (
select t.*,
1 + count(*)
filter(where webid != lag_webid or ts > lag_ts + interval '30' minute)
over(partition by userid order by ts) session_id
from (
select t.*,
lag(webid, 1, webid) over(partition by userid order by ts) lag_webid,
lag(ts, 1, ts) over(partition by userid order by ts) lag_ts
from mytable t
) t
) t
有人有更好的解决方案来完成这个任务吗?谢谢!
脚本参考:https://dbfiddle.uk/-c3ZNO65
我尝试了几个查询,但无法获得正确的session_id。
1条答案
按热度按时间von4xj4u1#
您的数据有点棘手,但是由于您有一个rowid作为排序顺序,我们可以使用它来生成您想要的结果
| 劳伊德|用户识别码|网络标识符|会话标识|ts|第一个_ts|
| - ------|- ------|- ------|- ------|- ------|- ------|
| 1个|A类|三十四|1个|2023年1月31日16时34分49秒|2023年1月31日16时34分49秒|
| 第二章|A类|七十三|第二章|2023年1月31日16时34分50秒|2023年1月31日16时34分50秒|
| 三个|A类|九十七|三个|2023年1月31日16时34分58秒|2023年1月31日16时34分58秒|
| 四个|A类|十七|四个|2023年1月31日17时35分02秒|2023年1月31日17时35分02秒|
| 五个|A类|十七|四个|2023年1月31日17时35分07秒|2023年1月31日17时35分02秒|
| 六个|A类|十七|四个|2023年1月31日17时35分18秒|2023年1月31日17时35分02秒|
| 七|A类|十七|四个|2023年1月31日17时35分30秒|2023年1月31日17时35分02秒|
| 八个|A类|1个|五个|2023年1月31日17时35分37秒|2023年1月31日17时35分37秒|
| 九|A类|1个|五个|2023年1月31日17时35分38秒|2023年1月31日17时35分37秒|
| 十个|A类|七十七|六个|2023年1月31日17时35分41秒|2023年1月31日17时35分41秒|
| 十一|A类|七十七|六个|2023年1月31日17时35分42秒|2023年1月31日17时35分41秒|
| 十二|A类|十五|七|2023年1月31日17时35分42秒|2023年1月31日17时35分42秒|
| 十三|A类|四十四|八个|2023年1月31日17时35分42秒|2023年1月31日17时35分42秒|
| 十四|A类|1个|九|2023年1月31日17时35分42秒|2023年1月31日17时35分42秒|
| 十五|A类|七十七|十个|2023年1月31日17时35分45秒|2023年1月31日17时35分45秒|
| 十六|A类|四十四|十一|2023年1月31日17时35分45秒|2023年1月31日17时35分45秒|
| 十七|A类|1个|十二|2023年1月31日17时37分10秒|2023年1月31日17时37分10秒|
| 十八|A类|1个|十二|2023年1月31日17时37分12秒|2023年1月31日17时37分10秒|
| 十九|A类|七十七|十三|2023年1月31日17时37分14秒|2023年1月31日17时37分14秒|
| 二十个|A类|七十七|十三|2023年1月31日17时52分14秒|2023年1月31日17时37分14秒|
| 二十一|A类|七十七|十三|2023年1月31日18时12分14秒|2023年1月31日17时37分14秒|
| 二十二|A类|七十七|十四|2023年1月31日18时45分14秒|2023年1月31日18时45分14秒|
| 二十三|A类|七十七|十四|2023年1月31日18时55分15秒|2023年1月31日18时45分14秒|
| 1个|B|三十三|1个|2023年1月31日06:37:15|2023年1月31日06:37:15|
| 第二章|B|五十六|第二章|2023年1月31日06时40分15秒|2023年1月31日06时40分15秒|
fiddle