[英]postgres sql GROUP BY DATE with LEFT JOIN does not list ALL records from the right table
我正在嘗試按出勤時間戳的日期分組,同時列出分組日期的所有員工。 而且無論是否有出勤記錄,我都想列出所有可用的員工。
這是我生成查詢的嘗試,但它沒有列出每個生成日期的所有員工。
請參考我嘗試的sql代碼: https://dbfiddle.uk/?rdbms=postgres_13&fiddle=a971a7ac01fb2f4bc7458983c40a24bf
SELECT
a.created_at::date as created_date,
a.employee_id,
e.name,
e.division_id,
MIN(a.created_at::time) FILTER (WHERE a.activity_type = 1) as min_time_in,
MAX(a.created_at::time) FILTER (WHERE a.activity_type = 2) as max_time_out
FROM
attendance a
LEFT JOIN employee e on e.id = a.employee_id
GROUP BY created_date, a.employee_id, e.name, e.division_id
ORDER BY created_date, a.employee_id
結果顯示如下:
created_date employee_id name division_id min_time_in max_time_out
2020-11-18 1 John 1 07:10:25 20:01:05
2020-11-18 2 Amber 2 07:30:25 19:10:25
2020-11-18 3 Mike 1 07:50:25 19:22:38
2020-11-19 1 John 1 07:11:23 23:21:53
但是,我的目標是列出所有員工並按日期對 employee_id 記錄進行分組。 無論員工是否出勤,它都應該顯示一行日期。 如何生成如下所示的查詢:
created_date employee_id name division_id min_time_in max_time_out
2020-11-18 1 John 1 07:10:25 20:01:05
2020-11-18 2 Amber 2 07:30:25 19:10:25
2020-11-18 3 Mike 1 07:50:25 19:22:38
2020-11-18 4 Jimmy 1 null null
2020-11-18 5 Kathy 2 null null
2020-11-19 1 John 1 07:11:23 23:21:53
2020-11-19 2 Amber 2 null null
2020-11-19 3 Mike 1 null null
2020-11-19 4 Jimmy 1 null null
2020-11-19 5 Kathy 2 null null
這應該有效:
SELECT
d::date AS created_date
, e.id
, e.name
, e.division_id
, MIN(a.created_at::time) FILTER (WHERE a.activity_type = 1) as min_time_in
, MAX(a.created_at::time) FILTER (WHERE a.activity_type = 2) as max_time_out
FROM (SELECT MIN(created_at), MAX(created_at) FROM attendance) AS r(startdate,enddate)
, generate_series(
startdate::timestamp,
enddate::timestamp,
interval '1 day') g(d)
CROSS JOIN employee e
LEFT JOIN attendance a ON a.created_at::date = d::date AND e.id = a.employee_id
GROUP BY
created_date
, e.id
, e.name
, e.division_id
ORDER BY
created_date
, e.id;
編輯:所選員工的 id,而不是 employee_id
只需將出勤表中的不同日期與員工表交叉連接即可。 您可以嘗試如下:
select
a1. date,
e.id,
e.name,
e.division_id,
MIN(a.created_at::time) FILTER (WHERE a.activity_type = 1 ) as min_time_in,
MAX(a.created_at::time) FILTER (WHERE a.activity_type = 2) as max_time_out
from
employee e left join (select distinct date(created_at) "date" from attendance ) a1 on true
left JOIN attendance a on e.id=a.employee_id and date(a.created_at)=a1.date
group by 1,2,3,4
order by 1,2
注意: left join on true
相當於cross join
更新:
如果您想要最小日期和最大日期之間的所有日期的 output。
with cte as (select min(created_at)::date "mindate", max(created_at)::date "maxdate" from attendance )
select
a1. date,
e.id,
e.name,
e.division_id,
MIN(a.created_at::time) FILTER (WHERE a.activity_type = 1 ) as min_time_in,
MAX(a.created_at::time) FILTER (WHERE a.activity_type = 2) as max_time_out
from
employee e
left join (select g.date from cte, generate_series(cte.mindate,cte.maxdate,interval '1 day') g(date) ) a1 on true
left JOIN attendance a on e.id=a.employee_id and date(a.created_at)=a1.date
group by 1,2,3,4
order by 1,2
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.