如何在SQL中分割这些多行?

问题描述 投票:0回答:2

我目前正在学习SQL,还是个新手。我有一个任务,需要用日期和用户 ID 等各种条目拆分一些行。我真的需要帮助

+-------+------------------------------+---------------------------+
| TYPE  |            DATES             |         USER _ID          |
+-------+------------------------------+---------------------------+
| WORK  | ["2022-06-02", "2022-06-03"] | {74042,88357,83902,88348} |
| LEAVE | ["2022-05-16", "2022-05-26"] | {83902,74042,88357,88348} |
+-------+------------------------------+---------------------------+

最终结果应该是这样的。用户 ID 应对齐或应与其各自的日期相同。

+-------+------------+---------+
| TYPE  |   DATES    | USER_ID |
+-------+------------+---------+
| LEAVE | 05/16/2022 |   74042 |
| LEAVE | 05/16/2022 |   88357 |
| LEAVE | 05/16/2022 |   88348 |
| LEAVE | 05/16/2022 |   83902 |
| LEAVE | 05/26/2022 |   74042 |
| LEAVE | 05/26/2022 |   88357 |
| LEAVE | 05/26/2022 |   88348 |
| LEAVE | 05/26/2022 |   83902 |
| WORK  | 06/2/2022  |   74042 |
| WORK  | 06/2/2022  |   88357 |
| WORK  | 06/2/2022  |   88348 |
| WORK  | 06/2/2022  |   83902 |
| WORK  | 06/3/2022  |   74042 |
| WORK  | 06/3/2022  |   88357 |
| WORK  | 06/3/2022  |   88348 |
| WORK  | 06/3/2022  |   83902 |
+-------+------------+---------+
sql postgresql data-cleaning unnest
2个回答
1
投票

创建表:

CREATE TABLE work_leave (
    TYPE varchar,
    DATES date,
    USER_ID integer
);

INSERT INTO work_leave
    VALUES ('LEAVE', '05/16/2022', 74042),
    ('LEAVE', '05/16/2022', 88357),
    ('LEAVE', '05/16/2022', 88348),
    ('LEAVE', '05/16/2022', 83902),
    ('LEAVE', '05/26/2022', 74042),
    ('LEAVE', '05/26/2022', 88357),
    ('LEAVE', '05/26/2022', 88348),
    ('LEAVE', '05/26/2022', 83902),
    ('WORK', '06/2/2022', 74042),
    ('WORK', '06/2/2022', 88357),
    ('WORK', '06/2/2022', 88348),
    ('WORK', '06/2/2022', 83902),
    ('WORK', '06/3/2022', 74042),
    ('WORK', '06/3/2022', 88357),
    ('WORK', '06/3/2022', 88348),
    ('WORK', '06/3/2022', 83902);

WITH date_ends AS (
    SELECT
        type,
        ARRAY[min(dates),
        max(dates)] AS dates
    FROM
        work_leave
    GROUP BY
        type
),
users AS (
    SELECT
        type,
        array_agg(DISTINCT (user_id)
        ORDER BY user_id) AS user_ids
FROM
    work_leave
GROUP BY
    type
)
SELECT
    de.type,
    de.dates,
    u.user_ids
FROM
    date_ends AS de 
JOIN 
    users as u 
ON de.type = u.type;

type  |          dates          |         user_ids          
-------+-------------------------+---------------------------
 LEAVE | {05/16/2022,05/26/2022} | {74042,83902,88348,88357}
 WORK  | {06/02/2022,06/03/2022} | {74042,83902,88348,88357}


1
投票

为了简单起见,我稍微调整了数据。这是一个想法:

WITH rows (type, dates, user_id) AS (
       VALUES ('WORK',  array['2022-06-02', '2022-06-03'], array[74042,88357,83902,88348])
            , ('LEAVE', array['2022-05-16', '2022-05-26'], array[83902,74042,88357,88348])
     )
SELECT r1.type, x.*
  FROM rows AS r1
  CROSS JOIN LATERAL (
      SELECT r2.dates, r3.user_id
        FROM unnest(r1.dates)   AS r2(dates)
           , unnest(r1.user_id) AS r3(user_id)
    ) AS x
;

小提琴

结果:

类型 日期 用户ID
工作 2022-06-02 74042
工作 2022-06-02 88357
工作 2022-06-02 83902
工作 2022-06-02 88348
工作 2022-06-03 74042
工作 2022-06-03 88357
工作 2022-06-03 83902
工作 2022-06-03 88348
离开 2022-05-16 83902
离开 2022-05-16 74042
离开 2022-05-16 88357
离开 2022-05-16 88348
离开 2022-05-26 83902
离开 2022-05-26 74042
离开 2022-05-26 88357
离开 2022-05-26 88348
© www.soinside.com 2019 - 2024. All rights reserved.