📜  SQL | WITH子句

📅  最后修改于: 2021-09-08 16:01:04             🧑  作者: Mango

SQL WITH 子句是由 Oracle 在 Oracle 9i 第 2 版数据库中引入的。 SQL WITH 子句允许您为子查询块命名(该过程也称为子查询重构),该名称可以在主 SQL 查询中的多个位置引用。

  • 该子句用于定义临时关系,以便该临时关系的输出可用,并由与 WITH 子句关联的查询使用。
  • 也可以使用嵌套子查询编写具有关联 WITH 子句的查询,但这样做会增加读取/调试 SQL 查询的复杂性。
  • 并非所有数据库系统都支持 WITH 子句。
  • 分配给子查询的名称被视为内联视图或表
  • SQL WITH 子句是由 Oracle 在 Oracle 9i 第 2 版数据库中引入的。

句法:

WITH temporaryTable (averageValue) as
    (SELECT avg(Attr1)
    FROM Table)
    SELECT Attr1
    FROM Table
    WHERE Table.Attr1 > temporaryTable.averageValue;
 

在这个查询中,WITH 子句用于定义一个只有 1 个属性averageValue 的临时关系临时表。 averageValue 保存关系表中描述的 Attr1 列的平均值。 WITH 子句后面的 SELECT 语句将只生成关系表中 Attr1 的值大于从 WITH 子句语句获得的平均值的那些元组。

注意:当执行带有 WITH 子句的查询时,首先会评估该子句中提到的查询,并将此评估的输出存储在一个临时关系中。在此之后,最终执行与 WITH 子句关联的主查询,该查询将使用生成的临时关系。

查询

示例 1:查找工资高于所有员工平均工资的所有员工。
关系名称:员工

EmployeeID Name Salary
100011 Smith 50000
100022 Bill 94000
100027 Sam 70550
100845 Walden 80000
115585 Erik 60000
1100070 Kate 69000

SQL查询:

WITH temporaryTable(averageValue) as
    (SELECT avg(Salary)
    from Employee)
        SELECT EmployeeID,Name, Salary 
        FROM Employee, temporaryTable 
        WHERE Employee.Salary > temporaryTable.averageValue;

输出

EmployeeID Name Salary
100022 Bill 94000
100845 Walden 80000

说明:所有员工的平均工资为70591。因此,所有工资高于求得的平均值的员工都属于产出关系。

例2:找出该航空公司所有飞行员的总薪水超过数据库中所有飞行员总薪水的平均值的所有航空公司。

关系名称:飞行员

EmployeeID Airline Name Salary
70007 Airbus 380 Kim 60000
70002 Boeing Laura 20000
10027 Airbus 380 Will 80050
10778 Airbus 380 Warren 80780
115585 Boeing Smith 25000
114070 Airbus 380 Katy 78000

SQL查询:

WITH totalSalary(Airline, total) as
    (SELECT Airline, sum(Salary)
    FROM Pilot
    GROUP BY Airline),
    airlineAverage(avgSalary) as 
    (SELECT avg(Salary)
    FROM Pilot )
    SELECT Airline
    FROM totalSalary, airlineAverage
    WHERE totalSalary.total > airlineAverage.avgSalary;

输出

Airline
Airbus 380

说明:空客380所有飞行员的总工资=298830,波音=45000。飞行员表中所有飞行员的平均工资=57305。因为只有空客380所有飞行员的总工资大于获得的平均工资,所以空客 380 在于输出关系。

要点:

  • SQL WITH 子句在与复杂的 SQL 语句而不是简单的语句一起使用时很好
  • 它还允许您将复杂的 SQL 查询分解为更小的查询,以便于调试和处理复杂的查询。
  • SQL WITH 子句基本上是对普通子查询的直接替换。