Postgresql 窗口函数的使用方法 row_number rank dense_rank over()

Postgresql 窗口函数的使用方法

导入数据库连接

  1. python版本 3.8
  2. 数据库软件postgresql 版本12.0
  3. ipython-sql 版本 4.0
  4. 目的 在jupyter notebook 界面使用数据库,实现数据中的窗口函数演示

 

image.png
# import sqlalchemy 
# 
# sqlalchemy.create_engine('postgresql://postgres:1234@localhost/postgres  ')
%load_ext sql
##  ipython-sql 载入sql命令环境
%sql postgresql://postgres:1234@localhost/postgres   
## 连接数据库,用户名postgres密码1234
%%sql 
DROP TABLE IF EXISTS "public"."products";
CREATE TABLE "public"."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 "public"."products" VALUES ('0006', 'iPhone X', '9600', null, '电器');
INSERT INTO "public"."products" VALUES ('0012', '电视', '3299', '4', '电器');
INSERT INTO "public"."products" VALUES ('0004', '辣条', '5.6', '4', '零食');
INSERT INTO "public"."products" VALUES ('0007', '薯条', '7.5', '1', '零食');
INSERT INTO "public"."products" VALUES ('0009', '方便面', '3.5', '1', '零食');
INSERT INTO "public"."products" VALUES ('0005', '铅笔', '7', '4', '文具');
INSERT INTO "public"."products" VALUES ('0014', '作业本', '1', null, '文具');
INSERT INTO "public"."products" VALUES ('0001', '鞋子', '27', '2', '衣物');
INSERT INTO "public"."products" VALUES ('0002', '外套', '110.9', '3', '衣物');
INSERT INTO "public"."products" VALUES ('0013', '围巾', '93', '5', '衣物');
INSERT INTO "public"."products" VALUES ('0008', '香皂', '17.5', '2', '日用品');
INSERT INTO "public"."products" VALUES ('0010', '水杯', '27', '3', '日用品');
INSERT INTO "public"."products" VALUES ('0015', '洗发露', '36', '1', '日用品');
INSERT INTO "public"."products" VALUES ('0011', '毛巾', '15', '1', '日用品');
INSERT INTO "public"."products" VALUES ('0003', '手表', '1237.55', '5', '电器');
INSERT INTO "public"."products" VALUES ('0016', '绘图笔', '15', null, '文具');
INSERT INTO "public"."products" VALUES ('0017', '汽水', '3.5', null, '零食');
COMMIT;
* postgresql://postgres:***@localhost/postgres
Done.
Done.
Done.
1 rows affected.
1 rows affected.
1 rows affected.
1 rows affected.
1 rows affected.
1 rows affected.
1 rows affected.
1 rows affected.
1 rows affected.
1 rows affected.
1 rows affected.
1 rows affected.
1 rows affected.
1 rows affected.
1 rows affected.
1 rows affected.
1 rows affected.
Done.





[]
%%sql 
select * from public.products
* postgresql://postgres:***@localhost/postgres
17 rows affected.
idnamepriceuidtype
0006iPhone X9600None电器
0012电视32994电器
0004辣条5.64零食
0007薯条7.51零食
0009方便面3.51零食
0005铅笔74文具
0014作业本1None文具
0001鞋子272衣物
0002外套110.93衣物
0013围巾935衣物
0008香皂17.52日用品
0010水杯273日用品
0015洗发露361日用品
0011毛巾151日用品
0003手表1237.555电器
0016绘图笔15None文具
0017汽水3.5None零食
%%sql
select type, name,price,row_number() over( order by price asc) as xuhao from public.products

--- 这里的窗口函数可以实现序号列,还可以按照over内的指定的列排序,该语句是按照price列进行升序排列
* postgresql://postgres:***@localhost/postgres
17 rows affected.
typenamepricexuhao
文具作业本11
零食汽水3.52
零食方便面3.53
零食辣条5.64
文具铅笔75
零食薯条7.56
日用品毛巾157
文具绘图笔158
日用品香皂17.59
日用品水杯2710
衣物鞋子2711
日用品洗发露3612
衣物围巾9313
衣物外套110.914
电器手表1237.5515
电器电视329916
电器iPhone X960017
%%sql
select type, name,price,rank() over( partition by type order by price asc) as rank from public.products

--- 这里实现分类排序,可以按照分类之间内部的价格排序,
--- 可能会出现并列的现象,同时序号会出现间断的情况
* postgresql://postgres:***@localhost/postgres
17 rows affected.
typenamepricerank
电器手表1237.551
电器电视32992
电器iPhone X96003
零食汽水3.51
零食方便面3.51
零食辣条5.63
零食薯条7.54
日用品毛巾151
日用品香皂17.52
日用品水杯273
日用品洗发露364
文具作业本11
文具铅笔72
文具绘图笔153
衣物鞋子271
衣物围巾932
衣物外套110.93
%%sql
select type, name,price,dense_rank() over( partition by type order by price asc) as ds_rank from public.products

--- 这里实现分类排序,可以按照分类之间内部的价格排序,
--- 可能会出现并列的现象,同时序号不少,注意辣条的排名从rank的第三名变成了第二名
* postgresql://postgres:***@localhost/postgres
17 rows affected.
typenamepriceds_rank
电器手表1237.551
电器电视32992
电器iPhone X96003
零食汽水3.51
零食方便面3.51
零食辣条5.62
零食薯条7.53
日用品毛巾151
日用品香皂17.52
日用品水杯273
日用品洗发露364
文具作业本11
文具铅笔72
文具绘图笔153
衣物鞋子271
衣物围巾932
衣物外套110.93
%%sql
select type, name,price,percent_rank() over( partition by type order by price asc) as ps_rank from public.products

--- 这里实现分类排序,可以按照分类之间内部的价格排序,
--- 百分比排名
* postgresql://postgres:***@localhost/postgres
17 rows affected.
typenamepriceps_rank
电器手表1237.550.0
电器电视32990.5
电器iPhone X96001.0
零食汽水3.50.0
零食方便面3.50.0
零食辣条5.60.666666666666667
零食薯条7.51.0
日用品毛巾150.0
日用品香皂17.50.333333333333333
日用品水杯270.666666666666667
日用品洗发露361.0
文具作业本10.0
文具铅笔70.5
文具绘图笔151.0
衣物鞋子270.0
衣物围巾930.5
衣物外套110.91.0
%%sql
select type, name,price,cume_dist() over( partition by type order by price asc) as cd_cume from public.products

--- 这里实现分类排序,可以按照分类之间内部的价格排序,
--- 累计百分比
* postgresql://postgres:***@localhost/postgres
17 rows affected.
typenamepricecd_cume
电器手表1237.550.333333333333333
电器电视32990.666666666666667
电器iPhone X96001.0
零食汽水3.50.5
零食方便面3.50.5
零食辣条5.60.75
零食薯条7.51.0
日用品毛巾150.25
日用品香皂17.50.5
日用品水杯270.75
日用品洗发露361.0
文具作业本10.333333333333333
文具铅笔70.666666666666667
文具绘图笔151.0
衣物鞋子270.333333333333333
衣物围巾930.666666666666667
衣物外套110.91.0
%%sql
select type, name,price,ntile(2) over( partition by type order by price asc) as fenzu from public.products

--- 这里实现分类排序,可以按照分类之间内部的价格排序,
--- 最大化均分,分桶
* postgresql://postgres:***@localhost/postgres
17 rows affected.
typenamepricefenzu
电器手表1237.551
电器电视32991
电器iPhone X96002
零食汽水3.51
零食方便面3.51
零食辣条5.62
零食薯条7.52
日用品毛巾151
日用品香皂17.51
日用品水杯272
日用品洗发露362
文具作业本11
文具铅笔71
文具绘图笔152
衣物鞋子271
衣物围巾931
衣物外套110.92

窗口函数和聚合函数同时使用

%%sql
select id,type,name,price,
sum(price) over(partition by type) 类别金额合计,
sum(price) over(order by type)/ sum(price) over() 类别总金额占所有金额的占比,
round(price /sum(price) over(partition by type),3) 金额占类别金额占比,
rank() over(partition by type order by price desc) 排名,
sum(price) over() 金额总计
from public.products 
order by type, price asc
* postgresql://postgres:***@localhost/postgres
17 rows affected.
idtypenameprice类别金额合计类别总金额占所有金额的占比金额占类别金额占比排名金额总计
0003电器手表1237.5514136.550.974527869406213269640.088314506.05
0012电器电视329914136.550.974527869406213269640.233214506.05
0006电器iPhone X960014136.550.974527869406213269640.679114506.05
0009零食方便面3.520.10.975913498161112087720.174314506.05
0017零食汽水3.520.10.975913498161112087720.174314506.05
0004零食辣条5.620.10.975913498161112087720.279214506.05
0007零食薯条7.520.10.975913498161112087720.373114506.05
0011日用品毛巾1595.50.982496958165730850230.157414506.05
0008日用品香皂17.595.50.982496958165730850230.183314506.05
0010日用品水杯2795.50.982496958165730850230.283214506.05
0015日用品洗发露3695.50.982496958165730850230.377114506.05
0014文具作业本1230.984082503507157358480.043314506.05
0005文具铅笔7230.984082503507157358480.304214506.05
0016文具绘图笔15230.984082503507157358480.652114506.05
0001衣物鞋子27230.91.000000000000000000000.117314506.05
0013衣物围巾93230.91.000000000000000000000.403214506.05
0002衣物外套110.9230.91.000000000000000000000.480114506.05
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值