如果时间戳落在指定的日期范围内,则更新时间戳
Updating timestamps if they fall within a specified date range
我目前正在使用 table,其中包含有关实体及其时间戳的信息。
架构看起来像这样 dat(id, created_time)
,id
作为主键。
如果时间戳介于周六凌晨 1 点到周一凌晨 1 点(不含)之间,我们希望将时间戳替换为周一凌晨 1 点。
我正在考虑使用 case 结构来查找时间戳落在星期六且时间大于 1:00.00 或时间戳落在星期日或时间戳落在星期一且时间小于 1:00.00 的实例比 1:00.00,并分配一个硬编码的日期和时间。
我认为这是一个常见问题,并且希望获得有关如何简化此问题的任何提示,或者是否存在可简化流程的功能。谢谢!
好吧,有几种方法可以做到这一点。我的答案都依赖于周日的会话可用 week_start
为 7
,并且 date_trunc 不支持 week_iso
,因此没有始终安全的解决方案。
alter session set week_start = 7;
SELECT
to_char(column1,'DY HH:MI') as t
,dayofweek(column1)=1 AND column1::time >= '01:00'::time as sun_after_1am
,dayofweek(column1)=2 AND column1::time < '01:00'::time as mon_before_1am
,iff(sun_after_1am OR mon_before_1am, dateadd('hour', 25, date_trunc('week', column1)), column1) as iff_answer
,case
when dayofweek(column1)=1 AND column1::time >= '01:00'::time
then dateadd('hour', 25, date_trunc('week', column1))
when dayofweek(column1)=2 AND column1::time < '01:00'::time
then dateadd('hour', 25, date_trunc('week', column1))
else column1
end as case_answer
,iff((dayofweek(column1)=1 AND column1::time >= '01:00'::time) OR (dayofweek(column1)=2 AND column1::time < '01:00'::time), dateadd('hour', 25, date_trunc('week', column1)), column1) as monster_iff_answer
,column1 between dateadd('hour', 1, date_trunc('week', column1))
and dateadd('hour', 25, date_trunc('week', column1))
FROM VALUES
('2022-03-31 09:09'::datetime),
('2022-03-28 08:09'::datetime),
('2022-03-28 00:12'::datetime),
('2022-03-27 23:33'::datetime),
('2022-03-27 01:01'::datetime),
('2022-03-27 00:02'::datetime)
ORDER BY column1;
T
SUN_AFTER_1AM
MON_BEFORE_1AM
IFF_ANSWER
CASE_ANSWER
MONSTER_IFF_ANSWER
BETWEEN_LOGIC
Sun 00:02
FALSE
FALSE
2022-03-27 00:02:00.000
2022-03-27 00:02:00.000
2022-03-27 00:02:00.000
FALSE
Sun 01:01
TRUE
FALSE
2022-03-28 01:00:00.000
2022-03-28 01:00:00.000
2022-03-28 01:00:00.000
TRUE
Sun 23:33
TRUE
FALSE
2022-03-28 01:00:00.000
2022-03-28 01:00:00.000
2022-03-28 01:00:00.000
TRUE
Mon 00:12
FALSE
TRUE
2022-03-28 01:00:00.000
2022-03-28 01:00:00.000
2022-03-28 01:00:00.000
TRUE
Mon 08:09
FALSE
FALSE
2022-03-28 08:09:00.000
2022-03-28 08:09:00.000
2022-03-28 08:09:00.000
FALSE
Thu 09:09
FALSE
FALSE
2022-03-31 09:09:00.000
2022-03-31 09:09:00.000
2022-03-31 09:09:00.000
FALSE
所以有两个测试 dayofweek
和一个 time
比较,它们在 IFF
中进行或运算
,dayofweek(column1)=1 AND column1::time >= '01:00'::time as sun_after_1am
,dayofweek(column1)=2 AND column1::time < '01:00'::time as mon_before_1am
,iff(sun_after_1am OR mon_before_1am, dateadd('hour', 25, date_trunc('week', column1)), column1) as iff_answer
然后是 CASE,我认为它实际上读起来更好:
,case
when dayofweek(column1)=1 AND column1::time >= '01:00'::time
then dateadd('hour', 25, date_trunc('week', column1))
when dayofweek(column1)=2 AND column1::time < '01:00'::time
then dateadd('hour', 25, date_trunc('week', column1))
else column1
end as case_answer
然后是 IFF 混在一起,太恶心了:
,iff((dayofweek(column1)=1 AND column1::time >= '01:00'::time) OR (dayofweek(column1)=2 AND column1::time < '01:00'::time), dateadd('hour', 25, date_trunc('week', column1)), column1) as monster_iff_answer
然后有一个 BETWEEN 只使用 DATE_TRUNC
,column1 between dateadd('hour', 1, date_trunc('week', column1))
and dateadd('hour', 25, date_trunc('week', column1)) as between_logic
无论如何,你说更新,所以这给了我一个统一的结果,一个 SELECT 或 VIEW 需要的可以分成一个 WHERE 子句
UPDATE table_name
SET date_time_column = dateadd('hour', 25, date_trunc('week', date_time_column ))
WHERE date_time_column BETWEEN dateadd('hour', 1, date_trunc('week', date_time_column))
AND dateadd('hour', 25, date_trunc('week', date_time_column))
我目前正在使用 table,其中包含有关实体及其时间戳的信息。
架构看起来像这样 dat(id, created_time)
,id
作为主键。
如果时间戳介于周六凌晨 1 点到周一凌晨 1 点(不含)之间,我们希望将时间戳替换为周一凌晨 1 点。
我正在考虑使用 case 结构来查找时间戳落在星期六且时间大于 1:00.00 或时间戳落在星期日或时间戳落在星期一且时间小于 1:00.00 的实例比 1:00.00,并分配一个硬编码的日期和时间。
我认为这是一个常见问题,并且希望获得有关如何简化此问题的任何提示,或者是否存在可简化流程的功能。谢谢!
好吧,有几种方法可以做到这一点。我的答案都依赖于周日的会话可用 week_start
为 7
,并且 date_trunc 不支持 week_iso
,因此没有始终安全的解决方案。
alter session set week_start = 7;
SELECT
to_char(column1,'DY HH:MI') as t
,dayofweek(column1)=1 AND column1::time >= '01:00'::time as sun_after_1am
,dayofweek(column1)=2 AND column1::time < '01:00'::time as mon_before_1am
,iff(sun_after_1am OR mon_before_1am, dateadd('hour', 25, date_trunc('week', column1)), column1) as iff_answer
,case
when dayofweek(column1)=1 AND column1::time >= '01:00'::time
then dateadd('hour', 25, date_trunc('week', column1))
when dayofweek(column1)=2 AND column1::time < '01:00'::time
then dateadd('hour', 25, date_trunc('week', column1))
else column1
end as case_answer
,iff((dayofweek(column1)=1 AND column1::time >= '01:00'::time) OR (dayofweek(column1)=2 AND column1::time < '01:00'::time), dateadd('hour', 25, date_trunc('week', column1)), column1) as monster_iff_answer
,column1 between dateadd('hour', 1, date_trunc('week', column1))
and dateadd('hour', 25, date_trunc('week', column1))
FROM VALUES
('2022-03-31 09:09'::datetime),
('2022-03-28 08:09'::datetime),
('2022-03-28 00:12'::datetime),
('2022-03-27 23:33'::datetime),
('2022-03-27 01:01'::datetime),
('2022-03-27 00:02'::datetime)
ORDER BY column1;
T | SUN_AFTER_1AM | MON_BEFORE_1AM | IFF_ANSWER | CASE_ANSWER | MONSTER_IFF_ANSWER | BETWEEN_LOGIC |
---|---|---|---|---|---|---|
Sun 00:02 | FALSE | FALSE | 2022-03-27 00:02:00.000 | 2022-03-27 00:02:00.000 | 2022-03-27 00:02:00.000 | FALSE |
Sun 01:01 | TRUE | FALSE | 2022-03-28 01:00:00.000 | 2022-03-28 01:00:00.000 | 2022-03-28 01:00:00.000 | TRUE |
Sun 23:33 | TRUE | FALSE | 2022-03-28 01:00:00.000 | 2022-03-28 01:00:00.000 | 2022-03-28 01:00:00.000 | TRUE |
Mon 00:12 | FALSE | TRUE | 2022-03-28 01:00:00.000 | 2022-03-28 01:00:00.000 | 2022-03-28 01:00:00.000 | TRUE |
Mon 08:09 | FALSE | FALSE | 2022-03-28 08:09:00.000 | 2022-03-28 08:09:00.000 | 2022-03-28 08:09:00.000 | FALSE |
Thu 09:09 | FALSE | FALSE | 2022-03-31 09:09:00.000 | 2022-03-31 09:09:00.000 | 2022-03-31 09:09:00.000 | FALSE |
所以有两个测试 dayofweek
和一个 time
比较,它们在 IFF
,dayofweek(column1)=1 AND column1::time >= '01:00'::time as sun_after_1am
,dayofweek(column1)=2 AND column1::time < '01:00'::time as mon_before_1am
,iff(sun_after_1am OR mon_before_1am, dateadd('hour', 25, date_trunc('week', column1)), column1) as iff_answer
然后是 CASE,我认为它实际上读起来更好:
,case
when dayofweek(column1)=1 AND column1::time >= '01:00'::time
then dateadd('hour', 25, date_trunc('week', column1))
when dayofweek(column1)=2 AND column1::time < '01:00'::time
then dateadd('hour', 25, date_trunc('week', column1))
else column1
end as case_answer
然后是 IFF 混在一起,太恶心了:
,iff((dayofweek(column1)=1 AND column1::time >= '01:00'::time) OR (dayofweek(column1)=2 AND column1::time < '01:00'::time), dateadd('hour', 25, date_trunc('week', column1)), column1) as monster_iff_answer
然后有一个 BETWEEN 只使用 DATE_TRUNC
,column1 between dateadd('hour', 1, date_trunc('week', column1))
and dateadd('hour', 25, date_trunc('week', column1)) as between_logic
无论如何,你说更新,所以这给了我一个统一的结果,一个 SELECT 或 VIEW 需要的可以分成一个 WHERE 子句
UPDATE table_name
SET date_time_column = dateadd('hour', 25, date_trunc('week', date_time_column ))
WHERE date_time_column BETWEEN dateadd('hour', 1, date_trunc('week', date_time_column))
AND dateadd('hour', 25, date_trunc('week', date_time_column))