postgres sql window 函数 - 尝试根据日期合并 array_agg 和 employee_id

postgres sql window function - trying to consolidate array_agg based on date and employee_id

我目前正在使用 postgres,并且有一个 sql window 函数用于根据日期生成员工签入和签出时间。但它有缺陷。

CREATE OR REPLACE VIEW view_test
 AS
 SELECT row_number() OVER () AS id,
    a.created_at::date AS created_at,
    date_part('year'::text, a.created_at) AS year,
    date_part('month'::text, a.created_at) AS month,
    date_part('day'::text, a.created_at) AS day,
    date_part('dow'::text, a.created_at) AS dow,
    a.company_id,
    a.employee_id,
    e.employee_type,
    array_agg(
        CASE
            WHEN a.activity_type = 1
            THEN a.created_at::time(0) 
            ELSE NULL::time
        END) AS time_in,
    array_agg(
        CASE
            WHEN a.activity_type = 2 
            THEN a.created_at::time(0) 
            ELSE NULL::time
        END) AS time_out
   FROM attendance_table a
     LEFT JOIN employee_table e ON e.id = a.employee_id
  GROUP BY a.created_at, date_part('day'::text, a.created_at),  
           a.employee_id, a.company_id, e.employee_type
  ORDER BY date_part('year'::text, a.created_at), date_part('month'::text, a.created_at), 
           date_part('day'::text, a.created_at), a.employee_id;

这会产生这个结果

我正在尝试以这种方式生成 time_in 和 time_out 是基于 created_at(日期)和 employee_id 合并的。这个想法是针对每个日期,我会知道员工的入住和退房时间。警告:如果数组中有记录,则不应出现 {NULL}。

我要操作的数据的视图和字段

https://docs.google.com/spreadsheets/d/1hn3w0mnezrV6_f-fPAKPZHuqdDjBBc_ArcgeBmgblq4/edit?usp=sharing

如何修改上面的 windows 函数 sql 视图,以便根据 created_at(日期)合并 time_in 和 time_out和 employee_id ? (最后一个屏幕截图是所需的输出)警告:如果数组中有记录,则不应出现 {NULL}。

更新(非常接近的答案但没有完全解决):

CREATE OR REPLACE VIEW view_group
 as 
 SELECT
    created_at,
    year,
    month,
    day,
    dow,
    company_id,
    employee_id,
    array_agg(check_in) as time_in,
    array_agg(check_out) as time_out
FROM
    view_test, unnest(time_in) check_in, unnest(time_out) check_out
GROUP BY 1,2,3,4,5,6,7  

它产生这个:

设法通过 unnest 连接数组。但请注意 NULL 仍然存在。如何删除 NULL(但如果什么都没有,NULL 应该在那里)?或有意义且可能的东西。

在不知道您的原始数据的情况下,我只能使用您当前的结果。

要将您的结果转换为预期结果,您可以简单地添加一个组步骤:

SELECT
    created_at,
    year,
    month,
    day,
    dow,
    company_id,
    employee_id,
    MAX(time_in) as time_in,
    MAX(time_out) as time_out
FROM
    -- <your query>
GROUP BY 1,2,3,4,5,6,7

编辑: 添加原始数据

您需要一个简单的枢轴步骤。这可以使用条件聚合(GROUP BYFILTER 子句)实现:

demo:db<>fiddle

SELECT 
    created_at::date,
    company_id,
    employee_id,
    MAX(created_at::time) FILTER (WHERE activity_type = 1),
    MAX(created_at::time) FILTER (WHERE activity_type = 2)
FROM
   attendance
GROUP BY created_at::date, company_id, employee_id