【发布时间】:2021-03-24 12:01:12
【问题描述】:
我有一个查询要根据按date 和employee_id 分组的日期系列生成报告。日期应基于特定时区,在本例中为“Asia/Kuala_Lumpur”。但这可能会根据用户所在时区的位置而改变。
SELECT
d::date AT TIME ZONE 'Asia/Kuala_Lumpur' AS created_date,
e.id,
e.name,
e.division_id,
ARRAY_AGG(
a.id
) as rows,
MIN(a.created_at) FILTER (WHERE a.activity_type = 1) as min_time_in,
MAX(a.created_at) FILTER (WHERE a.activity_type = 2) as max_time_out,
ARRAY_AGG(
CASE
WHEN a.activity_type = 1
THEN a.created_at
ELSE NULL
END
) as check_ins,
ARRAY_AGG(
CASE
WHEN a.activity_type = 2
THEN a.created_at
ELSE NULL
END
) as check_outs
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
where d::date = date '2020-11-20' and division_id = 1
GROUP BY
created_date
, e.id
, e.name
, e.division_id
ORDER BY
created_date
, e.id;
表attendance的定义和样本数据:
CREATE TABLE attendance (
id int,
employee_id int,
activity_type int,
created_at timestamp with time zone NOT NULL
);
INSERT INTO attendance VALUES
( 1, 1, 1,'2020-11-18 07:10:25 +00:00'),
( 2, 2, 1,'2020-11-18 07:30:25 +00:00'),
( 3, 3, 1,'2020-11-18 07:50:25 +00:00'),
( 4, 2, 2,'2020-11-18 19:10:25 +00:00'),
( 5, 3, 2,'2020-11-18 19:22:38 +00:00'),
( 6, 1, 2,'2020-11-18 20:01:05 +00:00'),
( 7, 1, 1,'2020-11-19 07:11:23 +00:00'),
( 8, 1, 2,'2020-11-19 16:21:53 +00:00'), <-- Asia/Kuala_Lumpur +8 should be in 20.11 (refer to the check_outs field in the results output)
( 9, 1, 1,'2020-11-19 19:11:23 +00:00'), <-- Asia/Kuala_Lumpur +8 should be in 20.11 (refer to the check_ins field in the results output)
(10, 1, 2,'2020-11-19 20:21:53 +00:00'), <-- Asia/Kuala_Lumpur +8 should be in 20.11 (refer to the check_outs field in the results output)
(11, 1, 1,'2020-11-20 07:41:38 +00:00'),
(12, 1, 2,'2020-11-20 08:52:01 +00:00');
这是一个fiddle 进行测试。
查询不包含时区 Asia/Kuala_Lumpur +8 的输出中的第 8-10 行,但它应该包含。结果显示“行”字段11,12。
如何修复查询,以便它根据给定时区的日期生成报告? (意味着我可以将Asia/Kuala_Lumpur 更改为America/New_York 等)
我被告知要做这样的事情:
where created_at >= timestamp '2020-11-20' AT TIME ZONE 'Asia/Kuala_Lumpur'
and created_at < timestamp '2020-11-20' AT TIME ZONE 'Asia/Kuala_Lumpur' + interval '1 day'
但我不确定如何应用它。在this fiddle 中似乎无法正常工作。它应该包括第 8、9、10、11、12 行,但只显示第 8、9、10 行。
【问题讨论】:
-
startdate和endate值的列类型是什么;时间戳,时间戳,还有别的吗?服务器TimeZone set to? So timestamps are being entered at 'UTC是什么,对吗?您是否尝试过类似的东西;startdate::timestamp AT TIME ZONE ' Asia/Kuala_Lumpur' , enddate::timestamp AT TIME ZONE ' Asia/Kuala_Lumpur'? -
我已更新以尝试使用 startdate 和 enddate dbfiddle.uk/…。 created_at timestamp with time zone
标签: sql postgresql date timezone generate-series