pgSql查询今天、昨天、本周、本月、上月、今年、去年的时间,以及计算时间之差

在项目遇到一个需求是查询统计今天、昨天、本周、本月、上月、今年、去年的时间数据,最近一个月的,最近一年的月份数据,使用的是pgSql数据库:

获取当前系统时间

select now();
select current_timestamp;
结果:2020-11-04 16:09:53.247825+08

获取当前日期或时间

select current_date;
结果:2020-11-04
select current_time;
结果:16:14:08.501182+08

查询昨天的数据

select 
	DISTINCT count(id)
from 
	表名
where coalesce(l.join_date,l.sys_createdate) >= current_date - 1;

# 这里的coalesce函数,语法:coalesce(expr1,expr2,expr3...)
# 如果第一个字段存在就用第一个进行表达式判断;
# 如果第一个不存在为null则用第二个进行表达式判断;
# 如果都没有null则返回null

查询某个时间的周一

SELECT ( DATE '2020-10-23' - INTERVAL '1 day' - ( EXTRACT ( dow FROM ( DATE'2020-10-23' - INTERVAL '1 day' ) ) - 1 || ' day' ) :: INTERVAL ) :: DATE;
# 减1 是因为得到的是以周一是星期的开始

查询本周的数据

SELECT( DATE ( now() ) - ( EXTRACT ( dow FROM DATE ( now() ) ) - 1 || ' day' ) :: INTERVAL ) :: DATE startasy,
( DATE ( now() ) - ( EXTRACT ( dow FROM DATE ( now() ) ) - 1 || ' day' ) :: INTERVAL ) :: DATE + 6 endday
	from 表名 LIMIT 1;

本周最后一天

SELECT to_char(CURRENT_DATE +cast(-1*(TO_NUMBER(to_char(CURRENT_DATE,'D'),'99')-2) + 6 ||' days' as interval),'yyyy-mm-dd');
# 加6天就表示是周日 不加就是本周的第一天

本月,方式一

select to_char((SELECT now() as timestamp),'mm');

本月,方式二

select * from 表名 where time >= date_trunc( 'month', now() ); 

获取上月

select to_char((select  now() - interval '1 month'),'mm');

获取今年

select to_char((SELECT now() as timestamp),'yyyy')

获取去年

select to_char((select  now() - interval '1 years'),'yyyy')

(补充)获取过去12个月或者今年月份的数据

WITH RECURSIVE T (n) AS (
SELECT DATE(to_char( to_date('2022-08', 'yyyy-MM-dd') - INTERVAL '11 month', 'yyyy-MM-dd' ))
UNION ALL
SELECT
n + 1
FROM
T
WHERE
n < DATE( to_char( to_date('2022-08', 'yyyy-MM-dd'), 'yyyy-MM-dd' ) )
) SELECT
to_char( n, 'yyyy-MM' ) AS MONTH
FROM T
GROUP BY
MONTH ORDER BY Month
# 只要月份修改成2022-12就表示查询今年内的所有月份

(补充)获取过去一个月内的所有天的数据

WITH RECURSIVE T ( n ) AS (
SELECT DATE
( to_char( now( ) - INTERVAL '30 day', 'yyyy-MM-dd' ) ) UNION ALL
SELECT
n + 1
FROM
T
WHERE
n < DATE ( to_char( now( ), 'yyyy-MM-dd' ) )
) SELECT
to_char( n, 'yyyy-MM-dd' ) AS DAYS
FROM T
GROUP BY
DAYS
ORDER BY DAYS

(补充)获取上个月每天的数据(1号-31号)

SELECT
 generate_series (
  date_trunc( 'month', CURRENT_DATE - interval '1 month'),
  date_trunc( 'month', CURRENT_DATE) - interval '1 day',
  '1 d' :: INTERVAL
 ) :: DATE days

(补充)获取本月每天的数据(1号-31号)

SELECT
 generate_series (
  date_trunc( 'month', CURRENT_DATE),
  date_trunc( 'month', CURRENT_DATE)  + '1 month -1d',
  '1 d' :: INTERVAL
 ) :: DATE days

(补充)获取某一天24小时的时刻

 select to_char(t,'yyyy-MM-DD HH24') as day
 from 
 generate_series('2022-01-01 00:00:00'::DATE,'2022-01-01 23:00:00', '1 hours') as t order by day asc;

或者这样写(方便传参):获取某一天24小时的时刻

SELECT
	to_char( T, 'yyyy-mm-dd HH24' ) AS HOUR 
FROM
	generate_series ( to_date( '2022-01-01', 'yyyy-MM-dd HH24:mi:ss' ), to_timestamp( concat ( '2022-01-01', ' 23:00:00' ), 'yyyy-mm-dd HH24:mi:ss' ), '1 hours' ) AS T 
ORDER BY
HOUR ASC;

同理,可获取某个月的所有天数据

SELECT
		to_char( T, 'yyyy-mm-dd' ) AS day
FROM
		generate_series ( to_date('2022-11', 'yyyy-MM'), (date_trunc('month', to_date('2022-11', 'yyyy-MM')) + interval '1 month - 1 day')::date, '1 days' ) AS T

同理,可获取某年的所有月份数据(上面写过相似的方法)

SELECT
	to_char( T, 'yyyy-MM' ) AS MONTH 
FROM
	generate_series ( to_date( concat ( '2022', '-01-01' ), 'yyyy-MM-dd' ), to_date( concat ( '2022', '-12-31' ), 'yyyy-MM-dd' ), '1 month' ) AS T 
ORDER BY
MONTH ASC

获取时间之间的秒差

SELECT round(date_part('epoch', TIMESTAMP '2022-08-15 17:00:10' - TIMESTAMP '2022-08-15 17:00:00'));
结果:10

获取时间之间的分钟差

SELECT round(date_part('epoch', TIMESTAMP '2022-08-15 17:10:10' - TIMESTAMP '2022-08-15 17:00:00')/60);
结果:10

获取时间之间的小时差

SELECT round(date_part('epoch', TIMESTAMP '2022-08-15 19:10:10' - TIMESTAMP '2022-08-15 17:00:00')/60/60);
结果:2
### PostgreSQL 中计算两个时间之间异的方法 在 PostgreSQL 中,可以通过多种方式来计算两个时间戳之间的异。以下是几种常见的方法: #### 使用 `age` 函数 `age` 是 PostgreSQL 提供的一个内置函数,用于返回两个日期或时间戳之间的异。它会以一种人类可读的方式展示结果,通常是以年、月、日的形式表示。 ```sql SELECT age('2023-10-01'::timestamp, '2022-08-15'::timestamp); ``` 上述查询的结果将以间隔形式显示,类似于 `1 year 1 mon 16 days`[^2]。 如果需要将结果转换为字符串以便进一步处理,可以使用 `CAST` 或者 `::text` 转换操作符: ```sql SELECT CAST(age('2023-10-01', '2022-08-15') AS VARCHAR); ``` 这将会把结果转化为字符型数据。 #### 时间戳直接相减 另一种简单的方式来获取两个时间戳之间的异是通过直接相减。这种方式适用于只需要精确到秒的情况: ```sql SELECT EXTRACT(EPOCH FROM ('2023-10-01 12:00:00'::timestamp - '2022-08-15 09:30:00'::timestamp)); ``` 此语句中的 `EXTRACT(EPOCH ...)` 将返回两时间戳间相的总秒数[^1]。 对于更复杂的单位(如小时、分钟),也可以利用类似的提取逻辑: ```sql -- 异以小时计 SELECT EXTRACT(EPOCH FROM ('2023-10-01'::timestamp - '2022-08-15'::timestamp)) / 3600; -- 异以天计 SELECT ('2023-10-01'::date - '2022-08-15'::date); ``` 以上两种情况分别展示了如何得到以小时和整天为单位的时间。 #### 自定义区间运算 当涉及到动态列或者表内的字段时,可以直接引用这些字段并执行相应的加减运算: ```sql SELECT now()::timestamp - col_timestamp AS time_diff_in_seconds, EXTRACT(DAY FROM (now()::timestamp - col_timestamp)) AS diff_days_only FROM your_table; ``` 这里假设存在一张名为 `your_table` 的表格,并且其中有一列表示某个特定时刻的数据叫做 `col_timestamp`。 --- ### 总结 综上所述,在 PostgreSQL 中有多个途径能够完成对两个时间距的测量工作,具体选择取决于实际需求以及期望获得的结果精度与表现形式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值