SQL WITH



有时您会面对一个无法轻易用单一的 SQL 语句回答的复杂问题。

您可以尝试通过使用多个内联视图或多个子查询来一次性得出答案,但这可能会使您的 SQL 难以理解,而一些版本的 SQL,如 Hive SQL,并不允许多个子查询。

第二种方法是将复杂性分解为几个不同的步骤。其中一种方法是创建多个表格,每个表格存储每个步骤的结果。这通常是一种不错的策略,因为这样做可以使调试变得更容易,并且更容易理解代码的执行方式。

然而,这个方法的问题是您需要在完成分析后记得删除这些表格;否则,这些表格将保留在数据库中,从而造成数据库管理问题。

创建多个表格的替代方法是在 SQL 中使用 WITH 子句。

语法

WITH 子句的基本语法如下:

WITH <query_name_1> AS (
SELECT 语句 1
)
主要 SELECT 语句

使用 WITH 子句的方式非常类似于创建表格。当您创建一个表格时,您会给它一个名称。同样地,当您使用 WITH 子句时,您也给它一个名称,这个名称在主 SQL 语句中的功能是跟表格一样。

由于 WITH 不创建表格或视观表,与 WITH 语句关联的对象在主SQL语句执行后消失,并且不需要进行清理。

您也可以一次用多个 WITH 子句。语法如下:

WITH <query_name_1> AS (
SELECT 语句 1
), <query_name_2> AS (
SELECT 语句 2
),
..
<query_name_n> AS (
SELECT 语句 N
)
主要 SELECT 语句

若要拥有多个 WITH 子句,您不需要多次指定 WITH。相反,在完成第一个 WITH 子句后,添加一个逗号,然后您可以以<query_name>开头,接着使用 AS 指定下一个子句。在最后一个 WITH 子句和主要 SQL 语句之间不需要逗号。

范例

我们在这页的范例中使用以下的表格。

Table Store_Sales
 Store_Name  Sales 
 Los Angeles  15000 
 San Diego  2500 
 New York  3000 
 Boston  7000 

范例 1: 在 SELECT 语句上使用 WITH

假设我们想列出所有销售额高于平均的店家。为了达到这个目标,我们可以使用以下的 WITH 语句:

WITH t1 AS (
SELECT AVG(Sales) AVG_SALES FROM Store_Sales
)
SELECT a1.* FROM Store_Sales a1, t1
WHERE a1.Sales > t1.AVG_SALES;

結果:

Store_Name Sales
Los Angeles 15000
Boston 7000

在这里,WITH 语句计算平均销售额(6,875),然后主要的 SQL 查询只需找出所有销售额列中的值大于此平均值的行。

使用内联视观表的等效 SQL 如下所示:

SELECT a1.* FROM Store_Sales a1,
(SELECT AVG(Sales) AVG_SALES FROM Store_Sales) t1
WHERE a1.Sales > t1.AVG_SALES;

同样地,我们可以可以通过以下使用子查询的 SQL 来获得同样的结果:

SELECT a1.* FROM Store_Sales a1
WHERE a1.Sales >
(SELECT AVG(Sales) AVG_SALES FROM Store_Sales);

请注意,由于 Hive SQL 并不支持子查询的用法,所以子查询版本不适用于 Hive SQL 上。

范例2: 在 CREATE TABLE语句上使用 WITH

我们也可以将 WITHCREATE TABLE 语句一起使用。假设我们想使用前面示例中的 WITH 子句来创建一个表格,我们将输入以下内容:

CREATE TABLE Above_Average_Sales
AS
WITH t1 AS (
SELECT AVG(Sales) AVG_SALES FROM Store_Sales
)
SELECT a1.* FROM Store_Sales a1, t1
WHERE a1.Sales > t1.AVG_SALES;

查询中的 WITH 部分应该在 CREATE TABLE AS 之后。请不要将 WITH 子句放在开头。以下查询将会产生错误:

WITH t1 AS (
SELECT AVG(Sales) AVG_SALES FROM Store_Sales
)
CREATE TABLE Above_Average_Sales
AS
SELECT a1.* FROM Store_Sales a1, t1
WHERE a1.Sales > t1.AVG_SALES;


SQL EXISTS >>

本页最近于 2023年10月16日更新



Copyright © 2024   1keydata.com   All Rights Reserved.