PostgreSQL练习2

Posted 一只小白two

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PostgreSQL练习2相关的知识,希望对你有一定的参考价值。

列转行
CREATE TABLE sdb.t_col_row
(id int,
c1 varchar(10),
c2 varchar(10),
c3 varchar(10)
)

INSERT INTO sdb.t_col_row( id, c1, c2, c3)VALUES (1, ‘v11‘, ‘v21‘, ‘v31‘);
INSERT INTO sdb.t_col_row( id, c1, c2, c3)VALUES (2, ‘v12‘, ‘v22‘, null);
INSERT INTO sdb.t_col_row( id, c1, c2, c3)VALUES (3, ‘v13‘, null, ‘v33‘);
INSERT INTO sdb.t_col_row( id, c1, c2, c3)VALUES (4, null, ‘v24‘, ‘v34‘);
INSERT INTO sdb.t_col_row( id, c1, c2, c3)VALUES (5, ‘v11‘, null, null);
INSERT INTO sdb.t_col_row( id, c1, c2, c3)VALUES (6, null, null, ‘v35‘);
INSERT INTO sdb.t_col_row( id, c1, c2, c3)VALUES (7, null, null, null);
commit;

select * from sdb.t_col_row;

select id,‘c1‘ cn,c1 from sdb.t_col_row;
select id,‘c2‘ cn,c2 from sdb.t_col_row;
select id,‘c3‘ cn,c3 from sdb.t_col_row;

行转列
CREATE TABLE sdb.t_row_col
as
select id,‘c1‘ cn,c1 cv
from sdb.t_col_row
union all
select id,‘c2‘ cn,c2 cv
from sdb.t_col_row
union all
select id,‘c3‘ cn,c3 cv
from sdb.t_col_row

select * from sdb.t_row_col
order by 1,2;

select id,
max(case when cn=‘c1‘ then cv else null end)as c1,
max(case when cn=‘c2‘ then cv else null end)as c2,
max(case when cn=‘c3‘ then cv else null end)as c3
from sdb.t_row_col
group by id
order by 1;

多行转成字符串
CREATE TABLE sdb.t_col_str
as
select * from sdb.t_col_row;

select * from sdb.t_col_str;

select id,c1||‘,‘||c2||‘,‘||c3 as c123
from sdb.t_col_str;

CREATE TABLE sdb.t_row_str
(
id int,col varchar(10)
);

INSERT INTO sdb.t_row_str( id, col)VALUES (1, ‘a‘);
INSERT INTO sdb.t_row_str( id, col) VALUES (1, ‘b‘);
INSERT INTO sdb.t_row_str(id, col)VALUES (1, ‘c‘);
INSERT INTO sdb.t_row_str( id, col) VALUES (2, ‘a‘);
INSERT INTO sdb.t_row_str( id, col) VALUES (2, ‘d‘);
INSERT INTO sdb.t_row_str( id, col)VALUES (2, ‘e‘);
INSERT INTO sdb.t_row_str( id, col) VALUES (3, ‘c‘);
commit;

select * from sdb.t_row_str;

select id,
max(case when rn=1 then col else null end)||
max(case when rn=2 then‘,‘||col else null end)||
max(case when rn=3 then‘,‘||col else null end) str
from (
select id,col,row_NUMBER() over(partition by id order by col) as rn
from sdb.t_row_str
)t
group by id
order by 1;

字符串转成多列
CREATE TABLE sdb.t_str_col
as select id,c1||‘,‘||c2||‘,‘||c3 as c123
from sdb.t_col_str;

select * from sdb.t_str_col;

select c123,split_part(c123,‘,‘,1),split_part(c123,‘,‘,2),split_part(c123,‘,‘,3)
from sdb.t_str_col;

字符串转成多行
CREATE TABLE sdb.t_str_row
as
select id,
max(case when rn=1 then col else null end)||
max(case when rn=2 then ‘,‘||col else null end)||
max(case when rn=3 then ‘,‘||col else null end) str
from (select id,
col,row_number() over(partition by id order by col) as rn
from sdb.t_row_str) t
group by id
order by 1;

select * from sdb.t_str_row;

select id,1 as p,split_part(str,‘,‘,1) as cv
from sdb.t_str_row
union all
select id,1 as p,split_part(str,‘,‘,2) as cv
from sdb.t_str_row
union all
select id,1 as p,split_part(str,‘,‘,3) as cv
from sdb.t_str_row
order by 1,2;


coalesce()函数:将空值替换成其他值,返回第一个非空值
coalesce(name,‘‘);

窗口函数
例子1:
DROP TABLE IF EXISTS empsalary;
CREATE TABLE empsalary(
depname varchar,
empno bigint,
salary int,
enroll_date date
);

INSERT INTO empsalary VALUES(‘develop‘,10, 5200, ‘2007/08/01‘);
INSERT INTO empsalary VALUES(‘sales‘, 1, 5000, ‘2006/10/01‘);
INSERT INTO empsalary VALUES(‘personnel‘, 5, 3500, ‘2007/12/10‘);
INSERT INTO empsalary VALUES(‘sales‘, 4, 4800, ‘2007/08/08‘);
INSERT INTO empsalary VALUES(‘sales‘, 6, 5500, ‘2007/01/02‘);
INSERT INTO empsalary VALUES(‘personnel‘, 2, 3900, ‘2006/12/23‘);
INSERT INTO empsalary VALUES(‘develop‘, 7, 4200, ‘2008/01/01‘);
INSERT INTO empsalary VALUES(‘develop‘, 9, 4500, ‘2008/01/01‘);
INSERT INTO empsalary VALUES(‘sales‘, 3, 4800, ‘2007/08/01‘);
INSERT INTO empsalary VALUES(‘develop‘, 8, 6000, ‘2006/10/01‘);
INSERT INTO empsalary VALUES(‘develop‘, 11, 5200, ‘2007/08/15‘);

select * from sdb.empsalary;
--统计人员所在部门的总薪水,平均薪水和部门的详细情况
select sum(salary) over(partition by empsalary.depname),avg(salary) over(partition by empsalary.depname),*
from sdb.empsalary;
--统计人员所在部门的薪水排名情况
select rank() over(partition by empsalary.depname order by salary),*
from sdb.empsalary;
--统计人员所在部门薪水排名,薪水级别,部门名称
select sum(salary) over(partition by empsalary.depname order by salary),salary,empsalary.depname
from sdb.empsalary;

例子2:
DROP TABLE IF EXISTS sdb.products;
CREATE TABLE sdb.products (
"id" varchar(10) COLLATE "default",
"name" text COLLATE "default",
"price" numeric,
"uid" varchar(14) COLLATE "default",
"type" varchar(100) COLLATE "default"
)
WITH (OIDS=FALSE);

BEGIN;
INSERT INTO sdb.products VALUES (‘0006‘, ‘iPhone X‘, ‘9600‘, null, ‘电器‘);
INSERT INTO sdb.products VALUES (‘0012‘, ‘电视‘, ‘3299‘, ‘4‘, ‘电器‘);
INSERT INTO sdb.products VALUES (‘0004‘, ‘辣条‘, ‘5.6‘, ‘4‘, ‘零食‘);
INSERT INTO sdb.products VALUES (‘0007‘, ‘薯条‘, ‘7.5‘, ‘1‘, ‘零食‘);
INSERT INTO sdb.products VALUES (‘0009‘, ‘方便面‘, ‘3.5‘, ‘1‘, ‘零食‘);
INSERT INTO sdb.products VALUES (‘0005‘, ‘铅笔‘, ‘7‘, ‘4‘, ‘文具‘);
INSERT INTO sdb.products VALUES (‘0014‘, ‘作业本‘, ‘1‘, null, ‘文具‘);
INSERT INTO sdb.products VALUES (‘0001‘, ‘鞋子‘, ‘27‘, ‘2‘, ‘衣物‘);
INSERT INTO sdb.products VALUES (‘0002‘, ‘外套‘, ‘110.9‘, ‘3‘, ‘衣物‘);
INSERT INTO sdb.products VALUES (‘0013‘, ‘围巾‘, ‘93‘, ‘5‘, ‘衣物‘);
INSERT INTO sdb.products VALUES (‘0008‘, ‘香皂‘, ‘17.5‘, ‘2‘, ‘日用品‘);
INSERT INTO sdb.products VALUES (‘0010‘, ‘水杯‘, ‘27‘, ‘3‘, ‘日用品‘);
INSERT INTO sdb.products VALUES (‘0015‘, ‘洗发露‘, ‘36‘, ‘1‘, ‘日用品‘);
INSERT INTO sdb.products VALUES (‘0011‘, ‘毛巾‘, ‘15‘, ‘1‘, ‘日用品‘);
INSERT INTO sdb.products VALUES (‘0003‘, ‘手表‘, ‘1237.55‘, ‘5‘, ‘电器‘);
INSERT INTO sdb.products VALUES (‘0016‘, ‘绘图笔‘, ‘15‘, null, ‘文具‘);
INSERT INTO sdb.products VALUES (‘0017‘, ‘汽水‘, ‘3.5‘, null, ‘零食‘);
COMMIT;

select*from sdb.products ;
--按price列升序
select type,name,price,row_number() over(order by price asc)as idx
from sdb.products;
--在类别内按照价格升序排列
select type,name,price,row_number() over(partition by type order by price asc)as idx
from sdb.products;
--分类排序序号并列 rank()
select type,name,price,rank() over(partition by type order by price asc)
from sdb.products;
--限制序号0-1之间 percernt_rank()
select type,name,price,percent_rank() over(partition by type order by price asc)
from sdb.products;
--限制序号在0-1之间相对排名
select type,name,price,cume_dist() over(partition by type order by price asc)
from sdb.products;
--限制最大序号为制定数字序号 ntile()
select type,name,price,ntile(2) over(partition by type order by price asc)
from sdb.products;
--获取分类子项排序中的第一条记录的某个字段的值
select type,name,price,first_value(name) over(partition by type order by price asc)
from sdb.products;
--窗口函数+聚合函数
select id,type,name,price,
sum(price) over w1 类别金额合计,
(sum(price) over (order by type))/sum(price) over() 类别总额占所有品类商品百分比,
rank() over w3 排名,
sum(price) over() 金额总计
from sdb.products
window
w1 as (partition by type),
w2 as (partition by type rows between unbounded preceding and unbounded following),
w3 as (partition by type order by price desc)
order by type,price asc;

以上是关于PostgreSQL练习2的主要内容,如果未能解决你的问题,请参考以下文章

Redhat 7.2 编译安装PostgreSQL 10

pg数据库的结构理解

AWS EC2:从 tomcat 7 连接到 PostgreSQL

14.3 Spark-SQL基于PostgreSQL数据分析编程实例

PostgreSQL练习3

PostgreSQL练习