数据库杂记

1. PostgreSQL

1.1 安装 UUID 生成扩展

-- 安装 UUID 生成扩展
create extension "pgcrypto";
-- 生成 UUID
select gen_random_uuid() uuid;
-- 删除 UUID 生成扩展
drop extension "pgcrypto";

1.2 根据多个字段去重,并删除重复数据(保留一条)

根据去重字段分组,ID 最小的一条数据保留,其他重复数据删除。

select * 
from student_info 
where (sno, sname) in (select sno, sname from student_info group by sno, sname having count(1) > 1)
and id not in (select min(id) from student_info group by sno, sname having count(1) > 1);

1.3 表字段更新

1.3.1 同一张表用一个字段更新另一个字段

-- 方法一
update student_info t1 set sname = t2.snickname from student_info t2 where t1.id = t2.id;
-- 方法二
update student_info t1 set sname = (select snickname from student_info where id = t1.id);

1.3.2 两张表关联更新

update student_info t1 set score_sum = t2.score_sum from score_info t2 where t1.sno = t2.sno;

注:学生表(student_info) 和 成绩表(score_info) 之间通过 sno 关联。

1.3.3 多张表关联更新

update student_info t1
set grade_name = t2.grade_name, total_score = t2.score_sum
from (
	select tmp1.sno, tmp2.grade_name, tmp1.score_sum
	from score_info tmp1
	inner join grade_info tmp2 on tmp1.gno = tmp2.gno
) t2
where t1.sno = t2.sno;

注:学生表(student_info) 和 成绩表(score_info) 之间通过 sno 关联;年级表(grade_info) 和 成绩表(score_info) 之间通过 gno 关联。

1.4 替换一个字段的部分内容

需求:现有一学号为 20211201,要求先在学号前面加上 DX,然后把 DX 替换为 空字符串,最终使该学号保持不变。

-- 在学号前面加上 DX (两种方法)
update student_info set sno = concat('DX', sno) where sno = '20211201';
update student_info set sno = 'DX' || sno where sno = '20211201';
-- 把 DX 替换为 空字符串(两种方法)
update student_info set sno = replace(sno, E'DX', '') where sno = 'DX20211201';
update student_info set sno = replace(sno, E'DX', '') where sno like E'%20211201';

1.5 计算百分比并保留两位小数

需求:计算 1 号学生英语成绩占语文、数学、英语三科成绩的百分比。

select round(coalesce(t2.english_score, 0::bigint)::numeric * 100::numeric / (t2.chinese_score + t2.math_score + t2.english_score)::numeric, 2) || '%'::text as percentage_of_english_score
from student_info t1
left join score_info t2 on t1.sno = t2.sno 
where t1.sno = '1';

1.6 类型转换

1.6.1 基本类型之间的转换

PostgreSQL 所有基本类型之间的转换只需要在字段名称后面加上 :数据类型 即可。

-- 日期转换为 varchar
select admission_time::varchar from student_info where sno = '1';
-- 字符串转换为 float
select chinese_score::float from score_info where sno = '1';

1.6.2 字符串转换为时间

select * from student_info where admission_time = to_date('2021-09-01 00:00:00', 'YYYY-MM-dd HH24:mi:ss');
select * from student_info where admission_time = to_date('2021-09-01', 'YYYY-MM-dd');
select * from student_info where admission_time = to_date('2021-09', 'YYYY-MM');

1.7 操作用逗号分隔的字符串(当然可以是其他符号分隔)

1.7.1 某一字段的所有结果之间用逗号分隔

通过 string_agg(text, text) 函数即可实现。如,查询所有学生的学号并用逗号分隔

select string_agg(sno, ',') all_sno from student_info;

1.7.2 逗号分隔的字符串转换为表格

通过 regexp_split_to_table(text, text) 函数即可实现。

select regexp_split_to_table('1,2,3,4,5,6', ',') sno;

逗号分隔的字符串转换为表格

1.8 判断一个字段是否包含某个字符

select position('.' in '33.33') > 0;	// 33.33 包含字符 '.',返回值大于 0,结果为 true
select position('.' in '33') = 0;		// 33 不包含字符  '.',返回值等于 0,结果为 true

1.9 创建只读用户

-- 创建只读角色
CREATE ROLE 角色名称;

-- 对现有表授予访问权限
GRANT USAGE ON SCHEMA public TO 角色名称;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO 角色名称;

-- 对后面新增的表授予访问权限
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO 角色名称;

-- 创建用户并分配只读角色
CREATE USER 用户名称 WITH PASSWORD '密码';
GRANT 角色名称 TO 用户名称;

1.10 查看用户权限

-- 查看表权限
select * from information_schema.table_privileges where grantee='用户名称';

-- 查看 usage 权限表
select * from information_schema.usage_privileges where grantee='用户名称';

-- 查看存储过程(函数)相关权限表
select * from information_schema.routine_privileges where grantee='用户名称';
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值