Postgresql常见(花式)操作完全示例

这篇具有很好参考价值的文章主要介绍了Postgresql常见(花式)操作完全示例。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

案例说明

将Excel数据导入Postgresql,并实现常见统计(数据示例如下)

Postgresql常见(花式)操作完全示例,数据库,数据库

导入Excel数据到数据库

使用Navicat工具连接数据库,使用导入功能可直接导入,此处不做过多介绍,详细操作请看下图:

Postgresql常见(花式)操作完全示例,数据库,数据库Postgresql常见(花式)操作完全示例,数据库,数据库

Postgresql常见(花式)操作完全示例,数据库,数据库

点击“下一步”完成导入操作(导入完成后,我们将表名命名为“eatLog”)。

Postgresql常见(花式)操作完全示例,数据库,数据库

 给数据表添加自增主键

导入的数据是没有主键的,这样不利于我们对数据的管理(如:在查询时,没有数据主键不能对数据进行修改等),因此我们需要扩展主键字段

添加主键字段

修改表设计,增加主键id字段(此时请勿添加主键约束)

Postgresql常见(花式)操作完全示例,数据库,数据库

创建自增序列

Postgresql没有像Oracle、MySQL那样的默认自增序列,因此要实现自增,可以通过自定义序列来实现

create SEQUENCE seq_eatlog_id
start with 1
increment by 1
no MINVALUE
no MAXVALUE
cache 1;

语句说明:

seq_eatlog_id:自定义的自增序列名称,根据自己需要命名

start with 1:序列从1开始

increment 1:序列自增步长为1(每次加1)

no MINVALUE:没有最小值约束

no MAXVALUE:没有最大值约束

cache 1:在数据库中始终缓存下一个序列

更新序列到数据表

update "eatLog"
set id = nextval('seq_eatlog_id')

nextval函数可获取下一个序列,可使用  select nextval('seq_eatlog_id') 来查询下一个序列。

注:调用一次nextval(),序列将被消费掉,因此不要轻易使用nextval()来查询序列,避免序列顺序混乱。

Postgresql常见(花式)操作完全示例,数据库,数据库

此时id已填充为自增的序列值(此时可以再修改表设计,给该表增加主键非空约束,顺手把date字段的数据类型修改为日期类型,数据会自动转换)

 Postgresql常见(花式)操作完全示例,数据库,数据库

 给表主键增加自增序列

上面将主键已填充,但是在新增数据时,仍需手动添加主键,否则会提示主键为空问题。

insert into "eatLog" values('乔峰',to_date('2024-01-04','YYYY-MM-DD'),'吃拉面',null,'xiaofeng@tianlong.com');

题外话:

Postgresql的表名和字段都是区分大小写的,因此针对驼峰名称必须添加双引号进行操作,否则会提示表或字段不存在 

全大写或全小写的表名可以省略双引号

Postgresql常见(花式)操作完全示例,数据库,数据库

因此需要给主键id字段添加自增序列,以便后续新增数据。

alter table "eatLog" alter COLUMN id set DEFAULT nextval('seq_eatlog_id');

再次执行插入语句,即可添加成功(以后添加数据无需再管主键id字段了)。

Postgresql常见(花式)操作完全示例,数据库,数据库

常见日期操作

获取周

查询数据中的日期在当年第几周,并将周信息保存到数据库中,以便后续按周统计

表设计中增加“周(week)”字段

select date_part('week',date::timestamp) week from "eatLog";

将周信息更新到表中

update "eatLog"
set week = date_part('week',date::timestamp)

获取月

查询月份方式一(格式化字符方式):

select to_char(date,'MM') from "eatLog";

查询月份方式二(日期函数获取):

select date_part('month',date::timestamp) from "eatLog";

查询月份方式三(提取函数获取):

select extract(month from date) as month from "eatLog";

查询部分时段数据

select * from "eatLog" 
where date >= to_date('2024-01-05','YYYY-MM-DD')
AND date <= to_date('2024-01-08','YYYY-MM-DD')
and phone is not null

Postgresql常见(花式)操作完全示例,数据库,数据库

数据脱敏

Postgresql常见(花式)操作完全示例,数据库,数据库

姓名脱敏

使用“*”号代替姓名中除第一个字和最后一个字的所有字符,两个字的名字仅替换最后一个字。

----三字及以上姓名脱敏
update "eatLog" 
set name = concat(
	left(name,1),
	repeat('*', length(name) - 2),
	right(name,1)
)
where length(name) > 2;

----两字姓名脱敏
update "eatLog" 
set name = concat(
	left(name,1),
	repeat('*', length(name) - 1)
)
where length(name) = 2;

concat()函数:用于拼接字符串

left()函数:用于截取字符串,指定从左截取多少位

right()函数:用于截取字符串,指定从右截取多少位

repeat()函数:用于替换字符串,指定替换多少位

手机号脱敏

保留手机号前三位和后四位,其他信息用“*”号代替

update "eatLog"
set phone = concat(
	left(phone,3),
	repeat('*',length(phone) - 7),
	right(phone,4)
)

注:身份证、银行卡脱敏思路相同 

 邮箱脱敏

update "eatLog"
set email = concat(
	left(email,1),
	repeat('*',position('@' in email) - 2),
	substring(email from position('@' in email))
)

substring()函数:截取字符串

position()函数:定位字符或字符串所在下标位置

 Postgresql常见(花式)操作完全示例,数据库,数据库

数据统计

分组统计

根据周、饮食类型分组查询

select extract(week from t1.date) as week,t1.food,count(1)
from "eatLog" t1
group by extract(week from t1.date),t1.food
order by extract(week from t1.date)

Postgresql常见(花式)操作完全示例,数据库,数据库

行转列统计

统计所有数据

select * from crosstab(
	'select extract(week from t1.date) as week,t1.food,count(1)
from "eatLog" t1
group by extract(week from t1.date),t1.food
order by extract(week from t1.date),t1.food',
 'select food from "eatLog" 
 group by food 
 order by food'
)
as (
	week int,
	吃火锅 NUMERIC,
	吃拉面 NUMERIC,
	吃馒头 NUMERIC,
	吃米饭 NUMERIC,
	吃米线 NUMERIC,
	吃面条 NUMERIC
)
order by week

Postgresql常见(花式)操作完全示例,数据库,数据库

行转列使用crosstab(sql1,sql2)函数

参数说明:

        sql1:统计数据的语句

        sql2:行转列的列查询SQL

crosstab的sql1返回值中必须有且只有三个字段:

        第一个字段表示行ID(可由分组生成),

        第二个字段表示分组目录(即待转换列),

        第三个字段表示统计数据

as中的内容是转换的列名及列值类型,此处的列明必须完全列出,与实际数据相符,否则会报错误。

注一:

postgresql默认未安装扩展函数,因此要使用crosstab()函数,必须先启用扩展

使用命令:

CREATE EXTENSION IF NOT EXISTS tablefunc;

注二:

行转列时,sql2参数必须进行排序,若不排序,虽然能转成功,但是会发现数据可能已经混乱,postgresql在行转列时,通过as中指定顺序匹配,而非是通过字段名称匹配,所以orader by固定数据位置,很容易造成匹配错误(as中的顺序可以使用sql2执行之后确认是否一致)

 统计部分数据

select * from crosstab(
	'select extract(week from t1.date) as week,t1.food,count(1)
from "eatLog" t1
where t1.date >= to_date(''2024-01-05'',''YYYY-MM-DD'')
AND t1.date <= to_date(''2024-01-08'',''YYYY-MM-DD'')
group by extract(week from t1.date),t1.food
order by extract(week from t1.date),t1.food',
 'select food from "eatLog" 
 group by food 
 order by food'
)
as (
	week int,
	吃火锅 NUMERIC,
	吃拉面 NUMERIC,
	吃馒头 NUMERIC,
	吃米饭 NUMERIC,
	吃米线 NUMERIC,
	吃面条 NUMERIC
)
order by week

Postgresql常见(花式)操作完全示例,数据库,数据库

在crosstab的sql参数中,若已经使用了单引号('),则需要使用两个单引号('')表示一个单引号,用于转义,否则SQL执行报错

另外,SQL查询时,若表名或字段使用驼峰时,必须使用双引号修饰,否则会找不到对象(Postgresql严格区分大小写,全大写或全小写时可以省略双引号修饰)

自定义统计列

select * from crosstab(
	'select 
	extract(week from t1.date) as week,
	t1.food,
	count(1) food_count
from "eatLog" t1
where t1.date >= to_date(''2024-01-05'',''YYYY-MM-DD'')
AND t1.date <= to_date(''2024-01-08'',''YYYY-MM-DD'')
group by extract(week from t1.date),t1.food
order by extract(week from t1.date)',
 $$values('吃火锅'),('吃米饭'),('吃米线'),('吃面条')$$
)
as (
	week int,
	吃火锅 NUMERIC,
	吃米饭 NUMERIC,
	吃米线 NUMERIC,
	吃面条 NUMERIC
)
order by week

可通过$$values()$$来指定转哪些列,注意values()的顺序必须与as中的顺序一致

 Postgresql常见(花式)操作完全示例,数据库,数据库

其他操作

计算精度问题

试想,我们的数据是统计每周的饮食统计,那每种饮食在每周占比是多少呢?

select m1.week,m1.food,m1.food_count, 
	(
		select 
			count(1) week_count
		from "eatLog" t2
		where t2.date >= to_date('2024-01-05','YYYY-MM-DD')
		AND t2.date <= to_date('2024-01-08','YYYY-MM-DD')
		and extract(week from t2.date) = m1.week
		group by extract(week from t2.date)
		order by extract(week from t2.date)
	) week_count
from
(
select 
	extract(week from t1.date) as week,
	t1.food,
	count(1) food_count
from "eatLog" t1
where t1.date >= to_date('2024-01-05','YYYY-MM-DD')
AND t1.date <= to_date('2024-01-08','YYYY-MM-DD')
group by extract(week from t1.date),t1.food
order by extract(week from t1.date)
) m1
order by m1.week,m1.food

Postgresql常见(花式)操作完全示例,数据库,数据库

计算占比时请注意精度问题

select m1.week,m1.food,round(m1.food_count::numeric / 
	(
		select 
			count(1) week_count
		from "eatLog" t2
		where t2.date >= to_date('2024-01-05','YYYY-MM-DD')
		AND t2.date <= to_date('2024-01-08','YYYY-MM-DD')
		and extract(week from t2.date) = m1.week
		group by extract(week from t2.date)
		order by extract(week from t2.date)
	)::numeric * 100,2) "rate(%)"
from
(
select 
	extract(week from t1.date) as week,
	t1.food,
	count(1) food_count
from "eatLog" t1
where t1.date >= to_date('2024-01-05','YYYY-MM-DD')
AND t1.date <= to_date('2024-01-08','YYYY-MM-DD')
group by extract(week from t1.date),t1.food
order by extract(week from t1.date)
) m1
order by m1.week,m1.food

Postgresql常见(花式)操作完全示例,数据库,数据库

Postgresql在计算时默认使用int来计算,因此不会取小数,若需要保留小数,需指明参加运算的字段类型,可通过“::numeric”来指明运算字段为数字型,这样运算结果可以保留小数

要具体精确到多少位,需要使用round()函数

行转列后效果

select * from crosstab(
	'select m1.week,m1.food,round(m1.food_count::numeric / 
	(
		select 
			count(1) week_count
		from "eatLog" t2
		where t2.date >= to_date(''2024-01-05'',''YYYY-MM-DD'')
		AND t2.date <= to_date(''2024-01-08'',''YYYY-MM-DD'')
		and extract(week from t2.date) = m1.week
		group by extract(week from t2.date)
		order by extract(week from t2.date)
	)::numeric * 100,2) "rate(%)"
from
(
select 
	extract(week from t1.date) as week,
	t1.food,
	count(1) food_count
from "eatLog" t1
where t1.date >= to_date(''2024-01-05'',''YYYY-MM-DD'')
AND t1.date <= to_date(''2024-01-08'',''YYYY-MM-DD'')
group by extract(week from t1.date),t1.food
order by extract(week from t1.date)
) m1
order by m1.week,m1.food',
 'select food from "eatLog" 
 group by food 
 order by food'
)
as (
	week int,
	吃火锅 NUMERIC,
	吃拉面 NUMERIC,
	吃馒头 NUMERIC,
	吃米饭 NUMERIC,
	吃米线 NUMERIC,
	吃面条 NUMERIC
)
order by week

Postgresql常见(花式)操作完全示例,数据库,数据库

以上,就是Postgresql在使用中常见操作及示例说明,希望对您有所帮助。 文章来源地址https://www.toymoban.com/news/detail-792554.html

到了这里,关于Postgresql常见(花式)操作完全示例的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Hbase数据库完全分布式搭建以及java中操作Hbase

    基础的环境准备不在赘述,包括jdk安装,防火墙关闭,网络配置,环境变量的配置,各个节点之间进行免密等操作等。使用的版本2.0.5. 参考官方文档 分布式的部署,都是在单节点服务的基础配置好配置,直接分发到其他节点即可。 jdk路径的配置,以及不适用内部自带的zk. 配

    2024年02月03日
    浏览(39)
  • JDBC连接GaussDB云数据库操作示例

    目录 一、实验环境 二、登录华为云创建测试库表 1、登录GaussDB云数据库 2、建库、建表,用于测试 3、新增普通角色(用户)用于登录及访问测试(可选) 4、获取对应的公网IP 三、创建java工程 1、创建java工程 2、添加jar包 3、编辑Java代码 四、执行并查看测试结果 1、本地JDB版

    2024年02月05日
    浏览(89)
  • 完全从零Java自学系列【入门篇】(第四课:Mysql服务端安装&使用客户端操作数据库&初识SQL基础操作&Java中使用第三方包&Java数据库操作&初步理解面相对象真正的意义之桥接设计模式)

      数据库是专门用来存储一系列集合数据的地方。所有的文件都可以被称之为库,当应用场景没那么复杂的时候,简单的应用程序用文本就可以了。数据库的意义是为了设计更好的保障数据安全(如多线程操作)、数据一致、索引(如何在庞大的数据中快速查找)等等一系

    2024年02月21日
    浏览(46)
  • 4、hive的使用示例详解-事务表、视图、物化视图、DDL(数据库、表以及分区)管理详细操作

    1、apache-hive-3.1.2简介及部署(三种部署方式-内嵌模式、本地模式和远程模式)及验证详解 2、hive相关概念详解–架构、读写文件机制、数据存储 3、hive的使用示例详解-建表、数据类型详解、内部外部表、分区表、分桶表 4、hive的使用示例详解-事务表、视图、物化视图、DDL

    2024年02月09日
    浏览(42)
  • openGauss学习笔记-201 openGauss 数据库运维-常见故障定位案例-执行修改表分区操作时报错

    201.1 执行修改表分区操作时报错 201.1.1 问题现象 执行ALTER TABLE PARTITION时,报错如下。 201.1.2 原因分析 在同一条ALTER TABLE PARTITION语句中,既存在DROP PARTITION又存在ADD PARTITION时,无论它们在语句中的顺序是什么,openGauss总会先执行DROP PARTITION再执行ADD PARTITION。执行完DROP PARTITIO

    2024年01月19日
    浏览(40)
  • postgresql|数据库|MySQL数据库向postgresql数据库迁移的工具pgloader的部署和初步使用

    MySQL数据库和postgresql数据库之间的差异并不多,这里的差异指的是对SQL语言的支持两者并不大,但底层的东西差异是非常多的,例如,MySQL的innodb引擎概念,数据库用户管理,这些和postgresql相比是完全不同的(MySQL用户就是用户,没有角色,postgresql有用户,有角色,但差异不

    2024年02月14日
    浏览(69)
  • PostgreSQL数据恢复:常见问题和解答

    本文将介绍关于PostgreSQL数据恢复的常见问题和解答。包括逻辑备份和物理备份的概念、基于时间点的恢复、WAL日志的使用、pg_dump和pg_restore的数据恢复方法,以及处理数据库损坏和预防数据丢失的措施。 1. 什么是PostgreSQL数据恢复? PostgreSQL数据恢复是指在数据库遭受损坏或数

    2024年02月12日
    浏览(25)
  • PostgreSQL 创建数据库

    PostgreSQL 创建数据库可以用以下三种方式: CREATE DATABASE 命令需要在 PostgreSQL 命令窗口来执行,语法格式如下: 例如,我们创建一个 runoobdb 的数据库: createdb 命令创建数据库 createdb 是一个 SQL 命令 CREATE DATABASE 的封装。 参数说明: . dbname:要创建的数据库名。 . description:关

    2024年02月12日
    浏览(43)
  • Postgresql数据库死锁

    ERROR: deadlock detected DETAIL: Process 95 waits for ShareLock on transaction 3553457; blocked by process 187. Process 187 waits for ShareLock on transaction 3553458; blocked by process 95. HINT: See server log for query details. CONTEXT: while updating tuple (0,6) in relation “deadlock_example” 其中 Process 95 在等待共享锁(ShareLock)的事务

    2024年01月20日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包