PostgreSQL窗口函数测试
简单记录下
测试数据如下:
表结构
\d products数据表 "public.products"栏位 | 类型 | 校对规则 | 可空的 | 预设
--------------+------------------------+----------+----------+----------------------------------------------product_id | integer | | not null | nextval('products_product_id_seq'::regclass)product_name | character varying(255) | | not null |price | numeric(11,2) | | |group_id | integer | | not null |
索引:"products_pkey" PRIMARY KEY, btree (product_id)
外部键(FK)限制:"products_group_id_fkey" FOREIGN KEY (group_id) REFERENCES product_groups(group_id)postgres=# \d product_groups数据表 "public.product_groups"栏位 | 类型 | 校对规则 | 可空的 | 预设
------------+------------------------+----------+----------+--------------------------------------------------group_id | integer | | not null | nextval('product_groups_group_id_seq'::regclass)group_name | character varying(255) | | not null |
索引:"product_groups_pkey" PRIMARY KEY, btree (group_id)
由引用:TABLE "products" CONSTRAINT "products_group_id_fkey" FOREIGN KEY (group_id) REFERENCES product_groups(group_id)
数据:
postgres=# table products;product_id | product_name | price | group_id
------------+--------------------+---------+----------1 | Microsoft Lumia | 200.00 | 12 | HTC One | 400.00 | 13 | Nexus | 500.00 | 14 | iPhone | 900.00 | 15 | HP Elite | 1200.00 | 26 | Lenovo Thinkpad | 700.00 | 27 | Sony VAIO | 700.00 | 28 | Dell Vostro | 800.00 | 29 | iPad | 700.00 | 310 | Kindle Fire | 150.00 | 311 | Samsung Galaxy Tab | 200.00 | 3
(11 行记录)postgres=# table product_groups;group_id | group_name
----------+------------1 | Smartphone2 | Laptop3 | Tablet
(3 行记录)
avg1是整个部门算平均值,avg2是同一部内当前行与之前的行的记录算平均值,因为w1没有指定range,因此默认使用between unbounded preceding and current rowselect t1.group_name,t2.product_id,t2.product_name,t2.price,
avg(t2.price) over w2 as avg1 ,
avg(t2.price) over w1 as avg2 ,
first_value(t2.price) over w1,
last_value(t2.price) over w2
from product_groups t1,products t2 where t1.group_id=t2.group_id
window w1 as (partition by t1.group_name order by t2.price) ,
window w2 as (partition by t1.group_name order by t2.price range between unbounded preceding and unbounded following);group_name | product_id | product_name | price | avg1 | avg2 | first_value | last_value
------------+------------+--------------------+---------+----------------------+----------------------+-------------+------------Laptop | 7 | Sony VAIO | 700.00 | 850.0000000000000000 | 700.0000000000000000 | 700.00 | 1200.00Laptop | 6 | Lenovo Thinkpad | 700.00 | 850.0000000000000000 | 700.0000000000000000 | 700.00 | 1200.00Laptop | 8 | Dell Vostro | 800.00 | 850.0000000000000000 | 733.3333333333333333 | 700.00 | 1200.00Laptop | 5 | HP Elite | 1200.00 | 850.0000000000000000 | 850.0000000000000000 | 700.00 | 1200.00Smartphone | 1 | Microsoft Lumia | 200.00 | 500.0000000000000000 | 200.0000000000000000 | 200.00 | 900.00Smartphone | 2 | HTC One | 400.00 | 500.0000000000000000 | 300.0000000000000000 | 200.00 | 900.00Smartphone | 3 | Nexus | 500.00 | 500.0000000000000000 | 366.6666666666666667 | 200.00 | 900.00Smartphone | 4 | iPhone | 900.00 | 500.0000000000000000 | 500.0000000000000000 | 200.00 | 900.00Tablet | 10 | Kindle Fire | 150.00 | 350.0000000000000000 | 150.0000000000000000 | 150.00 | 700.00Tablet | 11 | Samsung Galaxy Tab | 200.00 | 350.0000000000000000 | 175.0000000000000000 | 150.00 | 700.00Tablet | 9 | iPad | 700.00 | 350.0000000000000000 | 350.0000000000000000 | 150.00 | 700.00
(11 行记录)
postgres=# select t1.group_name,t2.product_id,t2.product_name,t2.price,
lag(t2.price,1) over w1 as prev_price,
t2.price-lag(t2.price) over w1 as cur_prev_diff from product_groups t1,products t2 where t1.group_id=t2.group_id
window w1 as (partition by t1.group_name order by t2.price);group_name | product_id | product_name | price | prev_price | cur_prev_diff
------------+------------+--------------------+---------+------------+---------------Laptop | 7 | Sony VAIO | 700.00 | |Laptop | 6 | Lenovo Thinkpad | 700.00 | 700.00 | 0.00Laptop | 8 | Dell Vostro | 800.00 | 700.00 | 100.00Laptop | 5 | HP Elite | 1200.00 | 800.00 | 400.00Smartphone | 1 | Microsoft Lumia | 200.00 | |Smartphone | 2 | HTC One | 400.00 | 200.00 | 200.00Smartphone | 3 | Nexus | 500.00 | 400.00 | 100.00Smartphone | 4 | iPhone | 900.00 | 500.00 | 400.00Tablet | 10 | Kindle Fire | 150.00 | |Tablet | 11 | Samsung Galaxy Tab | 200.00 | 150.00 | 50.00Tablet | 9 | iPad | 700.00 | 200.00 | 500.00
(11 行记录)