PostgreSQL

PostgreSQL 知识量:10 - 51 - 182

5.5 查询运算><

聚集运算- 5.5.1 -

在 PostgreSQL 中,可以使用聚合函数进行聚集运算。聚合函数可以对一组值执行计算,并返回单个值。以下是 PostgreSQL 中一些常用的聚合函数:

1. COUNT():计算行数。

SELECT COUNT(*) FROM table_name;

2. SUM():计算列的总和。

SELECT SUM(column_name) FROM table_name;

3. AVG():计算列的平均值。

SELECT AVG(column_name) FROM table_name;

4. MIN():返回列中的最小值。

SELECT MIN(column_name) FROM table_name;

5. MAX():返回列中的最大值。

SELECT MAX(column_name) FROM table_name;

6. STDDEV():计算列的标准偏差。

SELECT STDDEV(column_name) FROM table_name;

7. VARIANCE():计算列的方差。

SELECT VARIANCE(column_name) FROM table_name;

这些聚合函数可以单独使用,也可以与其他 SQL 语句(如 SELECT、GROUP BY 等)结合使用,以执行更复杂的聚集运算。例如,可以使用 GROUP BY 子句将结果按照某个列进行分组,并对每个组应用聚合函数。以下是一个示例:

SELECT department, COUNT(*) as employee_count, AVG(salary) as average_salary    
FROM employees    
GROUP BY department;

上述查询将按照部门对员工进行分组,并计算每个部门的员工数量和平均薪资。

分组运算- 5.5.2 -

可以使用 GROUP BY 子句进行分组运算。通过将数据按照某个列或多个列进行分组,可以对每个组执行聚合运算,如计数、求和、平均值等。

以下是使用 GROUP BY 进行分组运算的示例:

SELECT department, COUNT(*) as employee_count, AVG(salary) as average_salary    
FROM employees    
GROUP BY department;

上述查询将按照 department 列对员工进行分组,并计算每个部门的员工数量和平均薪资。

还可以使用 HAVING 子句对分组结果进行过滤。HAVING 子句在 GROUP BY 之后执行,类似于 WHERE 子句对原始数据进行过滤。以下是一个使用 HAVING 子句的示例:

SELECT department, COUNT(*) as employee_count, AVG(salary) as average_salary    
FROM employees    
GROUP BY department    
HAVING COUNT(*) > 10;

上述查询将按照 department 列对员工进行分组,并计算每个部门的员工数量和平均薪资。然后,使用 HAVING 子句过滤出员工数量大于 10 的部门。

表达式运算- 5.5.3 -

在 PostgreSQL 中,UNION、INTERSECT 和 EXCEPT 是用于组合两个或多个 SELECT 语句的结果集的操作符。这些操作符可以与 ALL 关键字一起使用,以指定是否包括重复的行。

1. UNION [ALL]:

UNION 操作符用于合并两个 SELECT 语句的结果集,并自动去除重复的行。

如果使用 UNION ALL,则保留所有的行,包括重复的行。语法示例:

SELECT column1, column2 FROM table1    
UNION      
SELECT column1, column2 FROM table2;

如果想保留重复的行,使用:

SELECT column1, column2 FROM table1    
UNION ALL      
SELECT column1, column2 FROM table2;

2. INTERSECT [ALL]:

INTERSECT 操作符用于返回两个 SELECT 语句结果集的交集。

与 UNION 类似,使用 INTERSECT ALL 会保留所有的行,包括重复的行。语法示例:

SELECT column1, column2 FROM table1    
INTERSECT      
SELECT column1, column2 FROM table2;

3. EXCEPT [ALL] 或 MINUS [ALL]:

EXCEPT 操作符用于返回第一个 SELECT 语句结果集减去第二个 SELECT 语句结果集的结果。

使用 EXCEPT ALL 会保留所有的行,包括重复的行。语法示例:

SELECT column1, column2 FROM table1    
EXCEPT      
SELECT column1, column2 FROM table2;

这些操作符在处理多个查询结果时非常有用,特别是当需要组合或比较来自不同表的数据时。注意:使用这些操作符时,每个 SELECT 语句必须具有相同数量的列,并且相应的列必须具有兼容的数据类型。

递归查询- 5.5.4 -

可以使用递归查询来处理具有层次结构或树形结构的数据。递归查询允许从一个表或视图中检索数据,并递归地检索与之相关联的其他表或视图的数据。

递归查询使用了一个名为 WITH RECURSIVE 的关键字,后面跟着一个递归查询定义,以及实际的查询语句。递归查询定义指定了要递归检索的表的名称和递归的条件。

以下是一个示例,演示了如何在 PostgreSQL 中执行递归查询:

WITH RECURSIVE hierarchy AS (  
  SELECT id, name, parent_id  
  FROM categories  
  WHERE parent_id IS NULL  
  UNION ALL  
  SELECT c.id, c.name, c.parent_id  
  FROM categories c  
  JOIN hierarchy h ON c.parent_id = h.id  
)  
SELECT * FROM hierarchy;

上述示例中,有一个名为 categories 的表,其中包含类别和父类别的信息。想要递归地检索所有的子类别,并将它们与它们的父类别一起显示出来。

在递归查询定义中,首先选择根类别(即没有父类别的类别),然后使用 UNION ALL 将它们与通过连接 categories 表和 hierarchy 视图(递归定义中的结果集)来检索的子类别进行合并。递归条件是通过将 categories 表与 hierarchy 视图进行连接,基于 parent_id 列来关联它们。最后,执行实际的查询语句,选择从 hierarchy 视图中检索的所有行。

窗口函数- 5.5.5 -

PostgreSQL 的窗口函数允许在一个数据集(或“窗口”)上执行计算,这个数据集由从当前行到指定的帧定义的其他行组成。这种功能非常适合执行与累计总计、移动平均、排名等相关的计算。

以下是 PostgreSQL 窗口函数的一些常见用法:

1. ROW_NUMBER():为结果集中的每一行分配一个唯一的数字。

SELECT name, score,    
ROW_NUMBER() OVER (ORDER BY score DESC) as rank    
FROM students;

2. RANK() 和 DENSE_RANK():为结果集中的每一行分配一个排名。

SELECT name, score,    
RANK() OVER (ORDER BY score DESC) as rank    
FROM students;

3. LAG() 和 LEAD():访问结果集中当前行之前的(或之后的)行。

SELECT name, score,    
LAG(score) OVER (ORDER BY score) as prev_score,    
LEAD(score) OVER (ORDER BY score) as next_score    
FROM students;

4. SUM()、AVG() 等聚合函数:在窗口中对值进行聚合计算。

SELECT name, score,    
SUM(score) OVER (ORDER BY name ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as cumulative_sum    
FROM students;

5. NTILE(n):将结果集中的行分成大致相等的 n 个组,并为每行分配一个桶号。

SELECT name, score,    
NTILE(4) OVER (ORDER BY score) as quartile_group    
FROM students;