这是SQL:
with action_a
as
(
SELECT user_id,
Row_number()
OVER (
ORDER BY a) id,
a
FROM (SELECT user_id,
CASE
WHEN action = 'a' THEN time
END "a"
FROM tabaction) x
),
action_b
as
(
SELECT user_id,
Row_number()
OVER (
ORDER BY b) id,
b
FROM (SELECT user_id,
CASE
WHEN action = 'b' THEN time
END "b"
FROM tabaction) x
),
action_c
as
(
SELECT user_id,
Row_number()
OVER (
ORDER BY c) id,
c
FROM (SELECT user_id,
CASE
WHEN action = 'c' THEN time
END "c"
FROM tabaction) x
)
SELECT action_a.user_id,
action_a.a,
action_b.b,
action_c.c
FROM action_a
FULL OUTER JOIN action_b
ON action_a.id = action_b.id
AND action_a.user_id = action_b.user_id
FULL OUTER JOIN action_c
ON action_b.id = action_c.id
AND action_b.user_id = action_c.user_id;
输出:
user_id | a | b | c
---------+---------------------+---------------------+---------------------
1 | 2022-01-01 12:30:00 | 2022-01-01 12:30:00 | 2022-01-01 12:00:00
1 | | 2022-01-01 12:50:00 | 2022-01-01 13:10:00
1 | | | 2022-01-01 13:20:00
1 | | |
1 | | |
1 | | |
(6 rows)
设置:
create table tabaction
( user_id int, action varchar(5) , time timestamp);
insert into tabaction values(1,'a','2022-01-01 12:30'),(1,'b','2022-01-01 12:30'),(1,'b','2022-01-01 12:50'),(1,'c','2022-01-01 12:00'),(1,'c','2022-01-01 13:10'),(1,'c','2022-01-01 13:20');
postgres=# select * from tabaction;
user_id | action | time
---------+--------+---------------------
1 | a | 2022-01-01 12:30:00
1 | b | 2022-01-01 12:50:00
1 | c | 2022-01-01 12:00:00
1 | c | 2022-01-01 13:10:00
1 | c | 2022-01-01 13:20:00
1 | b | 2022-01-01 12:30:00
(6 rows)
理想的 SQL 应该包括操作 A、B、C 的 user_id,以便那些不会错过的。这里没有出现这种情况,因为 USER_ID 只有 1 并且所有操作都映射到 USER_ID。我相信可能会有所不同,在这种情况下你可能需要这个 SQL:
with action_a
as
(
SELECT user_id,
Row_number()
OVER (
ORDER BY a) id,
a
FROM (SELECT user_id,
CASE
WHEN action = 'a' THEN time
END "a"
FROM tabaction) x
),
action_b
as
(
SELECT user_id,
Row_number()
OVER (
ORDER BY b) id,
b
FROM (SELECT user_id,
CASE
WHEN action = 'b' THEN time
END "b"
FROM tabaction) x
),
action_c
as
(
SELECT user_id,
Row_number()
OVER (
ORDER BY c) id,
c
FROM (SELECT user_id,
CASE
WHEN action = 'c' THEN time
END "c"
FROM tabaction) x
)
SELECT action_a.user_id a_userid,
action_b.user_id b_userid,
action_c.user_id c_userid,
action_a.a,
action_b.b,
action_c.c
FROM action_a
FULL OUTER JOIN action_b
ON action_a.id = action_b.id
AND action_a.user_id = action_b.user_id
FULL OUTER JOIN action_c
ON action_b.id = action_c.id
AND action_b.user_id = action_c.user_id;