经常需要计算时间的差值,时间相加。
SQL标准中 interval ‘1’ day
PostgresSQL中 interval ‘1 day’
-- add_months近似,动态添加
select to_date(col_1,'YYYYMMDD') + (col_2||' day')::interval from TABLE_NAME
-- 固定值
select to_date(col_1,'YYYYMMDD') + 3||'days'::interval from TABLE_NAME
-- 无效
--select startDt + interval nums || ' days' from TABLE_NAME;
-- 修改如下写法
select startDt + nums*interval '1' day from TABLE_NAME;
select startDt + nums*interval '1 days' from TABLE_NAME;
-- 标准SQL
select current_timestamp + cast((nums || ' days') as interval) from TABLE_NA
-- Postgres 9.4之后 make_interval()函数, Postgres 9.4失败
select startDt + make_interval(days=>nums) from TABLE_NAME;
-- Postgres特有写法
select current_timestamp + (nums || ' days')::interval from TABLE_NA
-- Postgres特有写法 ---不推荐
select current_timestamp + "interval" (nums || ' days')from TABLE_NA
CREATE OR REPLACE FUNCTION date_add(diffType varchar(15), step int, dateValue timestamp) RETURNS timestamp AS $$
DECLARE
YEAR_CONST Char(15) := 'year';
MONTH_CONST Char(15) := 'month';
WEEK_CONST Char(15) := 'week';
DAY_CONST Char(15) := 'day';
HOUR_CONST Char(15) := 'hour';
tmpDate timestamp;
intervals interval;
BEGIN
IF lower($1) = lower(YEAR_CONST) THEN
select cast(cast(step as character varying) || ' year' as interval) into intervals;
ELSEIF lower($1) = lower(MONTH_CONST) THEN
select cast(cast(step as character varying) || ' months' as interval) into intervals;
ELSEIF lower($1) = lower(DAY_CONST) THEN
select cast(cast(step as character varying) || ' day' as interval) into intervals;
ELSEIF lower($1) = lower(WEEK_CONST) THEN
select cast(cast(step as character varying) || ' week' as interval) into intervals;
ELSEIF lower($1) = lower(HOUR_CONST) THEN
select cast(cast(step as character varying) || ' hour' as interval) into intervals;
END IF;
tmpDate := dateValue + intervals;
RETURN tmpDate;
END;
$$ LANGUAGE plpgsql;
select date_add('day',1,current_timestamp);
已知需要添加多少秒、多少天时如下
-- 加1秒
select to_char(now() + interval '1 second', 'YYYY-MM-DD HH24:MI:SS') from TABLE_NAME;
-- 加1天
select to_char(now() + interval '1 day', 'YYYY-MM-DD HH24:MI:SS') from TABLE_NAME;
-- 分钟、小时类似单位改成minute、hour
-- 获取天
select extract(day from batch_date) from userinfo;
参考地址
-- 语法如下
DATE_ADD(date,INTERVAL expr type)
DATE_SUB(date,INTERVAL expr type)
ADDDATE(date,INTERVAL expr type)
SUBDATE(date,INTERVAL expr type)
语法:extract (field from source)
该函数得到 [double precision]类型值。
从日期或时间数值里提取年、月、日、小时等。
field:标识符或字符串,表示要抽取的子域。
source: timestamp、time、 interval 的值表达式,支持date。
field的值如下:
century,sec,min,hour,day(月的第几天),week(指定年的第几个周),month,quarter,year,decade(年份除10的值),millennium(第几个千年,0-1000第一个)
dow 日期是周几。如周日是0,周一是1
doy 年的第几天
epoch 1970-01-01 00:00:00 UTC到指定日期或指定时间戳之间相隔的秒数
两个时间差:age(timestamp, timestamp)
当前时间与传入时间的时间间隔:age(timestamp)
-- 秒数
select extract(epoch from (cast('20220615' as date) - (cast('20220615' as date)-interval '2 day') ));
-- 天数
select extract(day from(age('2022-06-05'::date,'2022-06-01'::date)));
-- DAYNUMBER_OF_MONTH
select extract(day from cast('20220605' as date));
-- DAYNUMBER_OF_YEAR
select extract(doy from cast('20220605' as date));
-- 1-12月
select extract(month from timestamp '2022-06-05 19:50:30');
-- 0-11,月数取模
select extract(month from interval '1 years 5 months');
提取日、年类似方式,month修改成day/year
select extract(epoch from age(to_timestamp('2022-06-05','YYYY-MM-DD'),to_timestamp('2022-06-01','YYYY-MM-DD')))
select extract(epoch from timestamp without time zone '2022-06-01 19:00:00');
select timestamp without time zone 'epoch' + 3600 * interval '1 second';
带时区,不带时区
-- 不带时区
select '2022-06-05 00:00:00'::timestamp(0);
-- 带时区
select to_timestamp('2022-06-05 00:00:00','YYYY-MM-DD HH24:MI:SS');
-- 将时间值转换时区
SELECT to_timestamp('2022-06-05 00:00:00','YYYY-MM-DD HH24:MI:SS'),to_timestamp('2022-06-05 00:00:00','YYYY-MM-DD HH24:MI:SS') AT TIME ZONE 'GMT';
得到子域
语法
date_part(text, timestamp)
date_part(text, interval)
text值如year,month,day,hour,minute,second等
select date_part('month', interval '1 years 5 months');
select date_part('hour', timestamp '2022-06-05 19:00:00');
截断成指定的精度,指定精度后面的子域用0补充
语法
date_trunc(text, timestamp)
date_trunc(text, interval)
text值如year,month,day,hour,minute,second等
date_trunc('hour', interval '1 days 11 hours 21 minutes');
语法
make_timestamp(year int, month int, day int, hour int, min int, sec double precision)
语法
make_timestamptz(year int, month int, day int, hour int, min int, sec double precision, [ timezone text ])
语法
make_date(year int, month int, day int)
语法
make_interval(years int DEFAULT 0, months int DEFAULT 0, weeks int DEFAULT 0, days int DEFAULT 0, hours int DEFAULT 0, mins int DEFAULT 0, secs double precision DEFAULT 0.0)
select make_interval(years := 1);
-- 类似oracle的list_agg
-- 1.支持将部门名称去重
select string_agg( distinct dept_name,'') deptArr FROM DEPT group by code;
deptArr
部门A,部门B
部门C,部门D
-- 2.支持排序
select string_agg( distinct dept_name,'',order by dept_name ) deptArr FROM DEPT group by code;
如一个管理部门有多个用户
select dept_name,array_to_string(ARRAY(select unnest(array_agg(user_name))),'') as users from deptinfo,userinfo where deptid=did group by detp_name
--部门A,张三,李四,王五
-- 支持排序
select dept_name,array_to_string(ARRAY(select unnest(array_agg(dept_alias order by dept_alias ))),'') as dept_desc from deptinfo group by dept_name;
select dept_name,string_agg(dept_alias,'') as dept_desc from deptinfo group by dept_name;
-- 查看acl相关函数
\df acl*
r -- SELECT ("read")
w -- UPDATE ("write")
a -- INSERT ("append")
d -- DELETE
D -- TRUNCATE
x -- REFERENCES
t -- TRIGGER
X -- EXECUTE
U -- USAGE
C -- CREATE
c -- CONNECT
T -- TEMPORARY
arwdDxt -- ALL PRIVILEGES (for tables, varies for other objects)
* -- grant option for preceding privilege
select usename from pg_user;
-- 元命令
-- 查看database
\l+
-- 查看schema
\dn+
-- 查看表
\dp table
-- 查看视图
\dp view
-- 查看序列
\dp sequence
-- 看用户系统权限
SELECT * FROM pg_roles WHERE rolname='test';
PSQL常用命令9.4版本
PSQL常用命令11版本