窗口函数类似与汇聚函数,不同的是汇聚函数会将 记录集数据 汇聚 成一条记录,而窗口函数则不会,窗口函数也是作用在记录集上,但返回结果不会减少记录行数。
下面给出具体例子:
我们创建产品和产品组两张表:
CREATE
TABLE
product_groups
(
group_id
serial
PRIMARY
KEY,
group_name
VARCHAR
(255)
NOT NULL
);
CREATE
TABLE
products
(
product_id
serial
PRIMARY
KEY,
product_name
VARCHAR
(255)
NOT NULL,
price
DECIMAL
(11,
2),
group_id
INT
NOT NULL,
FOREIGN
KEY
(group_id)
REFERENCES
product_groups
(group_id)
);
INSERT
INTO
product_groups
(group_name)
VALUES
(
'Smartphone'),
(
'Laptop'),
(
'Tablet');
INSERT
INTO
products
(product_name,
group_id,price)
VALUES
(
'Microsoft Lumia',
1,
200),
(
'HTC One',
1,
400),
(
'Nexus',
1,
500),
(
'iPhone',
1,
900),
(
'HP Elite',
2,
1200),
(
'Lenovo Thinkpad',
2,
700),
(
'Sony VAIO',
2,
700),
(
'Dell Vostro',
2,
800),
(
'iPad',
3,
700),
(
'Kindle Fire',
3,
150),
(
'Samsung Galaxy Tab',
3,
200);
汇聚函数avg计算每个产品组的平均价为例:
sql语句:
SELECT
group_name,
AVG
(price)
FROM
products
INNER JOIN
product_groups
USING
(group_id)
GROUP BY
group_name;
结果:
group_name
|
avg
------------+----------------------
Tablet
|
600
Smartphone
|
500
Laptop
|
800
(3
rows)
窗口功能:
SQL
SELECT
product_name,
price,
group_name,
AVG
(price)
OVER
(
PARTITION
BY
group_name)
FROM
products
INNER JOIN
product_groups
USING
(group_id);
结果:
product_name
|
price
|
group_name
|
avg
--------------------+---------+------------+----------------------
HP
Elite
|
900.00
|
Laptop
|
800
Lenovo
Thinkpad
|
1100.00
|
Laptop
|
800
Sony
VAIO
|
600.00
|
Laptop
|
800
Dell
Vostro
|
600.00
|
Laptop
|
800
Microsoft
Lumia
|
300.00
|
Smartphone
|
500
HTC
One
|
400.00
|
Smartphone
|
500
Nexus
|
500.00
|
Smartphone
|
500
iPhone
|
800.00
|
Smartphone
|
500
iPad
|
700.00
|
Tablet
|
600
Kindle
Fire
|
300.00
|
Tablet
|
600
Samsung
Galaxy
Tab
|
800.00
|
Tablet
|
600
(11
rows)
窗口函数语法:
window_function(arg1, arg2,..) OVER (PARTITION BY expression ORDER BY expression)
一个窗口函数执行在 JOIN, WHERE, GROUP BY 和HAVING子句之后,ORDER BY 子句之前。
内嵌窗口函数:
row_number(),
rank()
,
dense_rank()
first_value(), last_value()
, nth_value()
LAG(), LEAD() 等