With 子句

收藏647

阅读10263

更新时间2025-08-21

在 PostgreSQL 中,WITH 查询提供了一种编写辅助语句以用于更大查询的方法。 它有助于将复杂和大型查询分解为更简单的形式,这些形式易于阅读。 这些语句通常被称为公用表表达式或 CTE,可以被认为是定义仅用于一个查询的临时表。

WITH 查询是 CTE 查询,当子查询多次执行时特别有用。 代替临时表同样有用。 它计算一次聚合,并允许我们在查询中通过其名称(可能是多次)引用它。

在查询中使用 WITH 子句之前必须对其进行定义。

语法

WITH 查询的基本语法如下 −

WITH
   name_for_summary_data AS (
      SELECT Statement)
   SELECT columns
   FROM name_for_summary_data
   WHERE conditions <=> (
      SELECT column
      FROM name_for_summary_data)
   [ORDER BY columns]

其中 name_for_summary_data 是 WITH 子句的名称。 name_for_summary_data 可以与现有表名相同,并且优先。

您可以在 WITH 中使用数据修改语句(INSERT、UPDATE 或 DELETE)。 这允许您在同一个查询中执行几个不同的操作。


递归 WITH

递归 WITH 或分层查询是 CTE 的一种形式,其中 CTE 可以引用自身,即 WITH 查询可以引用其自己的输出,因此称为递归。

示例

考虑表COMPANY的记录如下 −

testdb# select * from COMPANY;
 id | name  | age | address   | salary
----+-------+-----+-----------+--------
  1 | Paul  |  32 | California|  20000
  2 | Allen |  25 | Texas     |  15000
  3 | Teddy |  23 | Norway    |  20000
  4 | Mark  |  25 | Rich-Mond |  65000
  5 | David |  27 | Texas     |  85000
  6 | Kim   |  22 | South-Hall|  45000
  7 | James |  24 | Houston   |  10000
(7 rows)

现在,让我们编写一个查询,使用 WITH 子句从上表中选择记录,如下所示 −

With CTE AS
(Select
 ID
, NAME
, AGE
, ADDRESS
, SALARY
FROM COMPANY )
Select * From CTE;

上面给出的 PostgreSQL 语句将产生以下结果 −

id | name  | age | address   | salary
----+-------+-----+-----------+--------
  1 | Paul  |  32 | California|  20000
  2 | Allen |  25 | Texas     |  15000
  3 | Teddy |  23 | Norway    |  20000
  4 | Mark  |  25 | Rich-Mond |  65000
  5 | David |  27 | Texas     |  85000
  6 | Kim   |  22 | South-Hall|  45000
  7 | James |  24 | Houston   |  10000
(7 rows)

现在,让我们使用 RECURSIVE 关键字和 WITH 子句编写一个查询,以查找小于 20000 的工资总和,如下所示 −

WITH RECURSIVE t(n) AS (
   VALUES (0)
   UNION ALL
   SELECT SALARY FROM COMPANY WHERE SALARY < 20000
)
SELECT sum(n) FROM t;

上面给出的 PostgreSQL 语句将产生以下结果 −

  sum
-------
 25000
(1 row)

让我们使用数据修改语句和 WITH 子句编写一个查询,如下所示。

首先,创建一个类似于表 COMPANY 的表 COMPANY1。 示例中的查询有效地将行从 COMPANY 移动到 COMPANY1。 WITH 中的 DELETE 从 COMPANY 中删除指定的行,并通过其 RETURNING 子句返回它们的内容; 然后主查询读取该输出并将其插入 COMPANY1 TABLE −

CREATE TABLE COMPANY1(
   ID INT PRIMARY KEY     NOT NULL,
   NAME           TEXT    NOT NULL,
   AGE            INT     NOT NULL,
   ADDRESS        CHAR(50),
   SALARY         REAL
);

WITH moved_rows AS (
   DELETE FROM COMPANY
   WHERE
      SALARY >= 30000
   RETURNING *
)
INSERT INTO COMPANY1 (SELECT * FROM moved_rows);

上面给出的 PostgreSQL 语句将产生以下结果 −

INSERT 0 3

现在,表 COMPANY 和 COMPANY1 中的记录如下 −

testdb=# SELECT * FROM COMPANY;
 id | name  | age |  address   | salary
----+-------+-----+------------+--------
  1 | Paul  |  32 | California |  20000
  2 | Allen |  25 | Texas      |  15000
  3 | Teddy |  23 | Norway     |  20000
  7 | James |  24 | Houston    |  10000
(4 rows)

testdb=# SELECT * FROM COMPANY1;
 id | name  | age | address | salary
----+-------+-----+-------------+--------
  4 | Mark  |  25 | Rich-Mond   |  65000
  5 | David |  27 | Texas       |  85000
  6 | Kim   |  22 | South-Hall  |  45000
(3 rows)

相关

视频

RELATED VIDEOS

更多

免费

phpStudy极速入门视频教程

免费

Midjourney基础课程
初级 Midjourney基础课程

11149次学习

收藏

免费

极客学院Git使用视频教程

免费

尚观shell视频教程
高级 尚观shell视频教程

15709次学习

收藏

免费

尚观Linux入门视频教程
初级 尚观Linux入门视频教程

42887次学习

收藏

免费

尚观Linux初级视频教程
初级 尚观Linux初级视频教程

40264次学习

收藏

免费

尚观Linux中级视频教程
中级 尚观Linux中级视频教程

48298次学习

收藏

免费

尚观Linux高级视频教程
高级 尚观Linux高级视频教程

41982次学习

收藏

科技资讯

更多

精选课程

更多
前端入门_HTML5
前端入门_HTML5

共29课时

61.7万人学习

CSS视频教程-玉女心经版
CSS视频教程-玉女心经版

共25课时

39.3万人学习

JavaScript极速入门_玉女心经系列
JavaScript极速入门_玉女心经系列

共43课时

70.9万人学习

独孤九贱(1)_HTML5视频教程
独孤九贱(1)_HTML5视频教程

共25课时

61.6万人学习

独孤九贱(2)_CSS视频教程
独孤九贱(2)_CSS视频教程

共22课时

23万人学习

独孤九贱(3)_JavaScript视频教程
独孤九贱(3)_JavaScript视频教程

共28课时

33.9万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时

125万人学习

关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号