0

嗨,我想知道如何在表格中使用交叉表来制作数据透视表,例如:

用户身份 行动 时间
1 一个 2022-01-01 12:30
1 b 2022-01-01 12:40
1 b 2022-01-01 12:50
1 C 2022-01-01 13:00
1 C 2022-01-01 13:10
1 C 2022-01-01 13:20
2 b 2022-01-01 13:11
2 C 2022-01-01 13:21

预期结果应如下所示:

用户身份 一个 b C
1 2022-01-01 12:30 2022-01-01 12:40 2022-01-01 13:00
1 无效的 2022-01-01 12:50 2022-01-01 13:10
1 无效的 无效的 2022-01-01 13:20
2 无效的 2022-01-01 13:11 2022-01-01 13:21

在几个教程之后,他们给了我这个结果:

用户身份 一个 b C
1 2022-01-01 12:30 2022-01-01 12:40 2022-01-01 13:00
2 无效的 2022-01-01 13:11 2022-01-01 13:21

但是,您可以注意到,单行结果会丢失大量数据。请问有人有什么想法吗?提前致谢

4

1 回答 1

0

这是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; 
于 2022-02-08T03:45:58.427 回答