VastbaseE100

基于开源技术的HTAP数据库管理系统。性能优异,稳定可靠,提供诸多专属领域特性。

Menu

SELECT

SELECT,TABLE,WITH - 从表或视图中检索行

语法格式

[ WITH [ RECURSIVE ] with_query [, ...] ]
SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ]
    [ * | expression [ [ AS ] output_name ] [, ...] ]
    [ FROM from_item [, ...] ]
    [ WHERE condition ]
    [ GROUP BY grouping_element [, ...] ]
    [ HAVING condition [, ...] ]
    [ WINDOW window_name AS ( window_definition ) [, ...] ]
    [ { UNION | INTERSECT | EXCEPT } [ ALL | DISTINCT ] select ]
    [ ORDER BY expression [ ASC | DESC | USING operator ] [ NULLS { FIRST | LAST } ] [, ...] ]
    [ LIMIT { count | ALL } ]
    [ OFFSET start [ ROW | ROWS ] ]
    [ FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } ONLY ]
    [ FOR { UPDATE | NO KEY UPDATE | SHARE | KEY SHARE } [ OF table_name [, ...] ] [ NOWAIT ] [...] ]

其中 from_item 可以是以下之一:

    [ ONLY ] table_name [ * ] [ [ AS ] alias [ ( column_alias [, ...] ) ] ]
                [ TABLESAMPLE sampling_method ( argument [, ...] ) [ REPEATABLE ( seed ) ] ]

    [ LATERAL ] ( select ) [ AS ] alias [ ( column_alias [, ...] ) ]
    with_query_name [ [ AS ] alias [ ( column_alias [, ...] ) ] ]
    [ LATERAL ] function_name ( [ argument [, ...] ] )
                [ WITH ORDINALITY ] [ [ AS ] alias [ ( column_alias [, ...] ) ] ]
    [ LATERAL ] function_name ( [ argument [, ...] ] ) [ AS ] alias ( column_definition [, ...] )
    [ LATERAL ] function_name ( [ argument [, ...] ] ) AS ( column_definition [, ...] )
    [ LATERAL ] ROWS FROM( function_name ( [ argument [, ...] ] ) [ AS ( column_definition [, ...] ) ] [, ...] )
                [ WITH ORDINALITY ] [ [ AS ] alias [ ( column_alias [, ...] ) ] ]
    from_item [ NATURAL ] join_type from_item [ ON join_condition | USING ( join_column [, ...] ) ]

并且 grouping_element 可以是以下之一:

    ( )
    expression
    ( expression [, ...] )
    ROLLUP ( { expression | ( expression [, ...] ) } [, ...] )
    CUBE ( { expression | ( expression [, ...] ) } [, ...] )
    GROUPING SETS ( grouping_element [, ...] )
    
并且 with_query 是:

    with_query_name [ ( column_name [, ...] ) ] AS ( select | values | insert | update | delete )

TABLE [ ONLY ] table_name [ * ]

说明

SELECT 从零个或多个表中检索行。 SELECT 的一般处理如下:

计算 WITH 列表中的所有查询。这些有效地用作可在 FROM列表中引用的临时表。在 FROM 中多次引用的 WITH 查询仅计算一次。 (见下文WITH Clause。)

计算 FROM 列表中的所有元素。 ( FROM列表中的每个元素都是真实或虚拟表。)如果在 FROM列表中指定了多个元素,它们将交叉连接在一起。 (见下文 FROM Clause。)

如果指定了 WHERE 子句,则从输出中消除所有不满足条件的行。 (见下文WHERE Clause。)

如果指定了 GROUP BY子句,或者存在聚合函数调用,则将输出组合成与一个或多个值匹配的行组,并计算聚合函数的结果。如果存在HAVING 子句,则会删除不满足给定条件的组。 (参见下面的 GROUP BYClause和 HAVING Clause。)

使用每个选定行或行组的 SELECT 输出表达式计算实际输出行。 (见下面的SELECT List。)

SELECT DISTINCT 从结果中删除重复的行。 SELECT DISTINCT ON消除了在所有指定表达式上匹配的行。 SELECT ALL(默认值)将返回所有候选行,包括重复行。 (见下面的 DISTINCTClause。)

使用运算符 UNION ,_ INTERSECT 和 EXCEPT ,可以组合多个 SELECT语句的输出以形成单个结果集。 UNION运算符返回一个或两个结果集中的所有行。 INTERSECT运算符返回两个结果集中严格的所有行。 EXCEPT运算符返回第一个结果集中但不在第二个结果集中的行。在所有三种情况下,除非指定了ALL ,否则将删除重复的行。可以添加干扰词 DISTINCT以明确指定消除重复行。请注意,DISTINCT 是此处的默认行为,即使 ALL 是SELECT 本身的默认行为。 (参见下面的 UNION Clause, INTERSECTClause和 EXCEPT Clause。)

如果指定了 ORDER BY 子句,则返回的行按指定的顺序排序。如果未给出 ORDER BY ,则以系统发现最快生成的顺序返回行。 (见下文 ORDER BY Clause。)

如果指定了 LIMIT (或 FETCH FIRST )或 OFFSET 子句,则 SELECT语句仅返回结果行的子集。 (见下文 LIMIT Clause。)

如果指定了 FOR UPDATE ,_ FOR NO KEY UPDATE , FOR SHARE 或 FOR KEY SHARE , SELECT 语句将锁定所选行以防止并发更新。 (见下文 The Locking Clause。)

您必须对 SELECT 命令中使用的每个列具有 SELECT 特权。 FOR NO KEY UPDATE, FOR UPDATE , FOR SHARE 或 FOR KEY SHARE 的使用也需要 UPDATE特权(对于如此选择的每个表的至少一列)。

参数说明

WITH 子句

WITH子句允许您指定一个或多个子查询,这些子查询可以在主查询中按名称引用。子查询在主查询的持续时间内有效地充当临时表或视图。每个子查询可以是SELECT , TABLE , VALUES , INSERT , UPDATE 或 DELETE 语句。在 WITH中编写数据修改语句(INSERT , UPDATE 或 DELETE )时,通常包含 RETURNING子句。它是 RETURNING的输出,而不是语句修改的基础表,它构成了主查询读取的临时表。如果省略RETURNING,则仍会执行该语句,但它不会生成任何输出,因此主查询不能将其作为表引用。

必须为每个 WITH查询指定名称(没有架构限定)。可选地,可以指定列名列表;如果省略,则从子查询推断列名称。

如果指定了 RECURSIVE ,则它允许 SELECT子查询按名称引用自身。这样的子查询必须具有该形式

non_recursive_term UNION [ ALL | DISTINCT ] recursive_term

其中递归自引用必须出现在 UNION的右侧。每个查询只允许一次递归自引用。不支持递归数据修改语句,但您可以在数据修改语句中使用递归SELECT 查询的结果。

RECURSIVE 的另一个影响是不需要对 WITH查询进行排序:查询可以引用列表中稍后的另一个查询。(但是,未实现循环引用或相互递归。)如果没有 RECURSIVE , WITH查询只能引用 WITH 列表中较早的同级 WITH 查询。

WITH查询的一个关键属性是,每次执行主查询时,它们仅被评估一次,即使主查询多次引用它们也是如此。特别是,无论主查询是读取所有输出还是任何输出,都保证数据修改语句只执行一次。

主要查询和 WITH 查询都是(名义上)同时执行的。这意味着除了通过读取其RETURNING 输出之外,无法从查询的其他部分看到 WITH中的数据修改语句的影响。如果两个此类数据修改语句尝试修改同一行,则结果未指定。

FROM 子句

FROM 子句为 SELECT指定一个或多个源表。如果指定了多个源,则结果是所有源的笛卡尔积(交叉连接)。但通常会添加资格条件(通过WHERE )将返回的行限制为笛卡尔积的一小部分。

FROM 子句可以包含以下元素:

  • table_name

    现有表或视图的名称(可选择模式限定)。如果在表名之前指定 ONLY,则仅扫描该表。如果未指定 ONLY ,则扫描表及其所有后代表(如果有)。(可选)可以在表名后指定 * 以明确指示包含后代表。

  • alias

    包含别名的 FROM项的替代名称。别名用于简洁或消除自连接的歧义(多次扫描同一个表)。提供别名时,它会完全隐藏表或函数的实际名称;例如,给定FROM foo AS f , SELECT 的剩余部分必须将此 FROM 项称为 f 而不是 foo。如果写入别名,则列别名列表可以也可以编写为表的一列或多列提供替代名称。

  • TABLESAMPLE sampling_method ( argument [, …] ) [ REPEATABLE ( seed) ]

    table_name之后的 TABLESAMPLE子句表示应该用指定的 sampling_method 来检索表中行的子集。这种采样优先于任何其他过滤器(例如 WHERE子句)。标准 PostgreSQL发布包括两种采样 方法:BERNOULLI和SYSTEM, 其他采样方法可以通过扩展安装在数据库中。

    BERNOULLI 和 SYSTEM 采样方法均接受单个 argument,它是要采样的表的一部分,表示为0到100之间的百分比。此参数说明可以是任何real -valued表达式。(其他抽样方法可能接受更多或不同的参数说明。)这两个方法都返回一个随机选择的表样本,该表将包含表格行的大约指定百分比。BERNOULLI 方法扫描整个表,并以指定的概率独立选择或忽略各个行。 SYSTEM方法对每个具有指定机会被选中的块进行块级采样;返回每个选定块中的所有行。当指定小的采样百分比时,SYSTEM 方法明显快于 BERNOULLI方法,但由于聚类效应,它可能返回表的较不随机的样本。

    可选的 REPEATABLE 子句指定用于在采样方法中生成随机数的 seed数字或表达式。种子值可以是任何非空浮点值。如果表没有同时更改,则指定相同种子和argument值的两个查询将选择表的相同样本。但是不同的种子值通常会产生不同的样本。如果未给出REPEATABLE,则基于系统生成的种子为每个查询选择新的随机样本。请注意,某些附加采样方法不接受REPEATABLE ,并且每次使用时都会产生新的样本。

  • select

    子 SELECT 可以出现在 FROM 子句中。这就像在单个 SELECT命令的持续时间内将其输出创建为临时表一样。请注意,子 SELECT 必须用括号括起来,并且必须为它提供别名。这里也可以使用 VALUES命令。

  • with_query_name

    通过写入其名称来引用 WITH 查询,就像查询的名称是表名一样。(实际上,为了主查询的目的, WITH查询会隐藏任何同名的实际表。如果需要,您可以通过模式限定表的名称来引用同名的实际表。)别名可以是提供方式与表格相同。

  • function_name

    函数调用可以出现在 FROM 子句中。(这对于返回结果集的函数尤其有用,但可以使用任何函数。)这就像在单个SELECT 命令的持续时间内将函数的输出创建为临时表一样。当将可选的 WITH ORDINALITY子句添加到函数调用中时,会在所有函数的输出列之后附加一个新列,并为每行编号。

    可以以与表相同的方式提供别名。如果写入别名,还可以编写列别名列表,以便为函数的复合返回类型的一个或多个属性提供替换名称,包括ORDINALITY 添加的列(如果存在)。

    通过用 ROWS FROM( … ) 包围它们,可以将多个函数调用组合成单个 FROM-clause项目。这样一个项的输出是每个函数的第一行的连接,然后是每个函数的第二行的连接,等等。如果某些函数产生的行少于其他函数,则用空值代替缺失的数据,这样返回的总行数始终与生成最多行的函数相同。

    如果函数已定义为返回 record 数据类型,则必须存在别名或关键字 AS ,然后是( column_name data_type [, … ])形式的列定义列表。列定义列表必须与函数返回的实际数量和列类型相匹配。

    使用 ROWS FROM( … )语法时,如果其中一个函数需要列定义列表,则最好将函数调用后的列定义列表放在ROWS FROM( … ) 中。只有当只有一个函数且没有 WITH ORDINALITY子句时,才能在 ROWS FROM( … ) 构造之后放置列定义列表。

    要将 ORDINALITY 与列定义列表一起使用,必须使用 ROWS FROM( … )语法并将列定义列表放在 ROWS FROM( … ) 中。

  • join_type

    • [ INNER ] JOIN

    • LEFT [ OUTER ] JOIN

    • RIGHT [ OUTER ] JOIN

    • FULL [ OUTER ] JOIN

    • CROSS JOIN

    对于 INNER 和 OUTER 加入类型,必须指定连接条件,即 NATURAL , ON join_condition 或 USING (join_column [, …])中的一个。请参阅下面的含义。对于 CROSS JOIN ,这些子句都不会出现。

    JOIN 子句组合了两个 FROM项,为方便起见,我们将其称为”表”,但实际上它们可以是任何类型的 FROM项。必要时使用括号来确定嵌套的顺序。在没有括号的情况下, JOIN 从左到右嵌套。在任何情况下 JOIN 都比分隔 FROM-list项目的逗号绑定得更紧密。

    CROSS JOIN 和 INNER JOIN 生成一个简单的笛卡尔积,与列出 FROM顶层的两个表得到的结果相同,但受连接条件限制(如果有的话)。 CROSS JOIN等同于 INNER JOIN ON (TRUE),即没有通过限定删除任何行。这些连接类型只是一种符号方便,因为它们对普通FROM 和 WHERE 无法做任何事情。

    LEFT OUTER JOIN返回限定笛卡尔积中的所有行(即,通过其连接条件的所有组合行),以及左侧表中没有通过连接条件的右侧行的每一行的一个副本。通过为右侧列插入空值,此左侧行扩展到连接表的整个宽度。请注意,在确定哪些行匹配时,仅考虑JOIN 子句自身的条件。之后应用外部条件。

    相反, RIGHT OUTER JOIN返回所有连接的行,每个不匹配的右侧行加一行(左侧用空值扩展)。这只是一种符号方便,因为您可以通过切换左右表将其转换为LEFT OUTER JOIN 。

    FULL OUTER JOIN返回所有连接的行,每个不匹配的左侧行加一行(右侧用空值扩展),每个不匹配的右侧行加一行(左侧用空值扩展)。

  • ON join_condition

    join_condition 是一个表达式,其值为 boolean (类似于 WHERE子句),指定连接中的哪些行被视为匹配。

    USING ( join_column [, …] )

    USING ( a, b, … ) 形式的子句是 ON left_table.a = right_table.a AND left_table.b = right_table.b … 的简写。此外, USING意味着每对等效列中只有一对将包含在连接输出中,而不是两者。

    NATURAL 是 USING列表的简写,它提到了两个表中具有匹配名称的所有列。如果没有公共列名,NATURAL 等同于 ON TRUE 。

    LATERAL 关键字可以在子 SELECT FROM 项之前。这允许子 SELECT 引用在 FROM列表中出现在它之前的 FROM 项的列。 (如果没有 LATERAL ,则每个子 SELECT都是独立计算的,因此不能交叉引用任何其他 FROM 项目。)

    LATERAL 也可以在函数调用 FROM项之前,但在这种情况下它是一个干扰词,因为函数表达式在任何情况下都可以引用之前的FROM 项。

    LATERAL 项目可以出现在 FROM 列表的顶层,也可以出现在 JOIN树中。在后一种情况下,它也可以指在 JOIN 左侧的任何项目,它位于右侧。

    当 FROM 项目包含 LATERAL交叉引用时,评估将按如下方式进行:对于提供交叉引用列的 FROM项目的每一行,或提供列的多个 FROM 项目的行集,将使用 LATERAL 项目评估LATERAL项目行或行集的列值。生成的行像往常一样连接它们的行。对列源表中的每行或每组行重复此操作。

    列源表必须是 INNER 或 LEFT 连接到 LATERAL项,否则将没有明确定义的行集来计算 LATERAL 项的每组行。因此,虽然诸如 X RIGHT JOIN LATERAL Y 之类的构造在语法上是有效的,但实际上不允许 Y 引用 X。

WHERE子句

可选的 WHERE 子句具有一般形式

WHERE condition

其中 condition 是任何计算结果类型为 boolean的表达式。任何不满足此条件的行都将从输出中删除。如果在实际行值替换任何变量引用时返回true,则行满足条件。

GROUP BY子句

可选的 GROUP BY 子句具有一般形式

GROUP BY grouping_element [, ...]

GROUP BY 会将所有选定的行压缩为一行,这些行共享相同的分组表达式值。grouping_element 中使用的 expression可以是输入列名称,也可以是输出列的名称或序号( SELECT list item),也可以是由输入列值组成的任意表达式。如果含糊不清,a GROUP BY name将被解释为输入列名称而不是输出列名称。

如果 GROUPING SETS , ROLLUP 或 CUBE 中的任何一个作为分组元素存在,那么GROUP BY 子句作为一个整体定义了一些独立的 grouping sets。这种效果相当于在子查询之间构造 UNION ALL ,并将各个分组集作为 GROUP BY 子句。

如果使用聚合函数,则在组成每个组的所有行中计算聚合函数,从而为每个组生成单独的值。(如果存在聚合函数但没有 GROUP BY 子句,则查询被视为具有包含所有选定行的单个组。)可以通过将 FILTER子句附加到聚合函数调用来进一步筛选馈送到每个聚合函数的行集。当存在FILTER 子句时,只有与其匹配的行才包含在该聚合函数的输入中。

当存在 GROUP BY 或存在任何聚合函数时, SELECT列表表达式无法引用未聚合的列,但聚合函数内或未分组的列在功能上依赖于分组列,因为否则会超过为未分组的列返回一个可能的值。如果分组列(或其子集)是包含未分组列的表的主键,则存在功能依赖性。

请记住,在评估 HAVING 子句或 SELECT列表中的任何”标量”表达式之前,将评估所有聚合函数。这意味着,例如, CASE表达式不能用于跳过聚合函数的评估。

目前, FOR NO KEY UPDATE , FOR UPDATE , FOR SHARE 和 FOR KEY SHARE不能与 GROUP BY 一起指定。

有条款

可选的 HAVING 子句具有一般形式

HAVING condition

其中 condition 与 WHERE 子句指定的相同。

HAVING 消除了不满足条件的组行。 HAVING 与 WHERE 不同: WHERE 在应用 GROUP BY 之前过滤各行,而 HAVING 过滤由 GROUP BY 创建的组行。 condition中引用的每一列必须明确引用分组列,除非引用出现在聚合函数内,或者未分组列在功能上依赖于分组列。

即使没有 GROUP BY 子句, HAVING的存在也会将查询转换为分组查询。这与查询包含聚合函数但没有 GROUP BY子句时发生的情况相同。所有选定的行都被视为组成一个组, SELECT list和HAVING 子句只能引用聚合函数中的表列。如果 HAVING条件为真,则此类查询将发出单行,如果不为真,则为零行。

目前, FOR NO KEY UPDATE , FOR UPDATE , FOR SHARE 和 FOR KEY SHARE不能与 HAVING 一起指定。

WINDOW条款

可选的 WINDOW 子句具有一般形式

WINDOW window_name AS ( window_definition ) [, ...]

其中 window_name 是可以从 OVER 子句或后续窗口定义引用的名称,window_definition 是

[ existing_window_name ]
[ PARTITION BY expression [, ...] ]
[ ORDER BY expression [ ASC | DESC | USING operator ] [ NULLS { FIRST | LAST } ] [, ...] ]
[ frame_clause ]

如果指定 existing_window_name ,则必须引用 WINDOW列表中的较早条目;新窗口从该条目复制其分区子句,以及它的排序子句(如果有的话)。在这种情况下,新窗口不能指定自己的PARTITION BY 子句,并且只有在复制的窗口没有窗口时才能指定 ORDER BY。新窗口总是使用自己的frame子句;复制的窗口不得指定frame子句。

PARTITION BY 列表的元素的解释方式与 GROUP BY Clause的元素大致相同,只是它们总是简单的表达式,而不是输出列的名称或编号。另一个区别是这些表达式可以包含聚合函数调用,这在常规GROUP BY子句中是不允许的。这里允许使用它们,因为在分组和聚合之后会发生窗口化。

类似地, ORDER BY 列表的元素的解释方式与 ORDER BY Clause的元素大致相同,只是表达式总是作为简单表达式而不是输出列的名称或编号。

可选的 frame_clause定义了依赖于框架的窗口函数的窗口框架(不是全部都是这样)。窗口框架是查询的每一行的一组相关行(称为当前行)。frame_clause 可以是其中之一

{ RANGE | ROWS | GROUPS } frame_start [ frame_exclusion ]
{ RANGE | ROWS | GROUPS } BETWEEN frame_start AND frame_end [ frame_exclusion ]

其中 frame_start 和 frame_end 可以是其中之一

UNBOUNDED PRECEDING
offset PRECEDING
CURRENT ROW
offset FOLLOWING
UNBOUNDED FOLLOWING

和 frame_exclusion 可以是其中之一

EXCLUDE CURRENT ROW
EXCLUDE GROUP
EXCLUDE TIES
EXCLUDE NO OTHERS

如果省略 frame_end ,则默认为 CURRENT ROW 。限制是 frame_start 不能UNBOUNDED FOLLOWING , frame_end 不能是 UNBOUNDED PRECEDING ,而frame_end 选择不能出现在上面的 frame_start 和 frame_end选项列表中,而不是 frame_start 选项 - 例如 RANGE BETWEEN CURRENT ROW AND offset PRECEDING 是不允许的。

默认框架选项是 RANGE UNBOUNDED PRECEDING ,与 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW相同;它将帧设置为从分区启动到当前行的最后一个对等体的所有行(窗口的ORDER BY 子句认为等效于当前行的行;如果没有 ORDER BY ,则所有行都是对等体)。通常, UNBOUNDED PRECEDING表示帧以分区的第一行开头,类似地 UNBOUNDED FOLLOWING表示帧以分区的最后一行结束,而不管 RANGE , ROWS 或 GROUPS 模式。在 ROWS模式中, CURRENT ROW 表示框架以当前行开始或结束;但是在 RANGE 或 GROUPS模式下,它表示该帧以 ORDER BY排序中的当前行的第一个或最后一个对等体开始或结束。 offset PRECEDING 和offset FOLLOWING 选项的含义因帧模式而异。在 ROWS 模式中, offset是一个整数,表示该帧在当前行之前或之后开始或结束那么多行。在 GROUPS模式中, offset是一个整数,表示该帧在当前行的对等组之前或之后开始或结束那么多对等组,其中对等组是根据窗口的ORDER BY 子句等效的一组行。在 RANGE 模式下,使用 offset选项要求窗口定义中只有一个 ORDER BY 列。然后该框架包含那些排序列值不小于offset (对于 PRECEDING )或大于(对于 FOLLOWING)当前行的排序列值的行。在这些情况下, offset表达式的数据类型取决于排序列的数据类型。对于数字排序列,它通常与排序列的类型相同,但对于日期时间排序列,它是interval 。在所有这些情况下, offset的值必须为非null且为非负值。此外,虽然 offset不必是简单常量,但它不能包含变量,聚合函数或窗口函数。

frame_exclusion选项允许从帧中排除当前行周围的行,即使它们将根据帧开始和帧结束选项包含在内。EXCLUDE CURRENT ROW 从帧中排除当前行。 EXCLUDE GROUP从帧中排除当前行及其排序对等项。 EXCLUDE TIES从帧中排除当前行的所有对等项,但不排除当前行本身。 EXCLUDE NO OTHERS只是明确指定了不排除当前行或其对等的默认行为。

请注意,如果 ORDER BY 排序没有对行进行唯一排序,则 ROWS模式会产生不可预测的结果。 RANGE 和 GROUPS 模式旨在确保 ORDER BY排序中的对等行被视为相似:给定对等组的所有行都将在帧中或从中排除。

WINDOW 子句的目的是指定出现在查询的 SELECT List或 ORDER BY Clause中的窗口函数的行为。这些函数可以在 OVER 子句中按名称引用 WINDOW 子句条目。但是,不必在任何地方引用 WINDOW子句条目;如果在查询中没有使用它,则会被忽略。可以使用没有任何 WINDOW子句的窗口函数,因为窗口函数调用可以直接在其 OVER子句中指定其窗口定义。但是,当多个窗口函数需要相同的窗口定义时, WINDOW子句可以保存输入。

目前,无法使用 WINDOW 指定 FOR NO KEY UPDATE , FOR UPDATE ,_ FOR SHARE 和 FOR KEY SHARE 。

SELECT列表

SELECT 列表(在关键字 SELECT 和 FROM 之间)指定了构成 SELECT 语句的输出行的表达式。表达式可以(通常也可以)引用 FROM 子句中计算的列。

就像在表中一样, SELECT 的每个输出列都有一个名称。在一个简单的 SELECT中,此名称仅用于标记要显示的列,但是当 SELECT 是较大查询的子查询时,较大的查询将该名称视为子项生成的虚拟表的列名称-query。要指定用于输出列的名称,请在列的表达式后面写入AS output_name 。 (您可以省略 AS ,但仅当所需的输出名称与任何Vastbase E100关键字都不匹配时(请参阅 Appendix C )。为防止将来可能添加关键字,建议您始终写入 AS或双引号输出名称。)如果未指定列名,则Vastbase E100会自动选择名称。如果列的表达式是a简单的列引用然后选择的名称与该列的名称相同。在更复杂的情况下,可以使用函数或类型名称,或者系统可以回退到生成的名称,例如?column? 。

输出列的名称可用于引用 ORDER BY 和 GROUP BY 子句中列的值,但不能用于WHERE 或 HAVING 子句中的列;那里你必须写出表达式。

可以在输出列表中写入 *而不是表达式,作为所选行的所有列的简写。此外,您可以将 table_name.*写为来自该表的列的简写。在这些情况下,无法使用 AS指定新名称;输出列名称将与表列的名称相同。

根据SQL标准,应在应用 DISTINCT , ORDER BY 或 LIMIT之前计算输出列表中的表达式。当使用 DISTINCT时,这显然是必要的,因为否则不清楚哪些值是不同的。但是,在许多情况下,如果在ORDER BY 和 LIMIT之后计算输出表达式,则很方便。特别是如果输出列表包含任何易失性或昂贵的函数。使用该行为,函数评估的顺序更直观,并且不会对与从未出现在输出中的行相对应的评估。 Vastbase E100将在排序和限制后有效地评估输出表达式,只要这些表达式未在DISTINCT , ORDER BY 或 GROUP BY 中引用。 (作为一个反例, SELECT f(x)FROM tab ORDER BY 1 显然必须在排序之前评估 f(x)。)包含集合返回函数的输出表达式在排序之后和限制之前被有效地计算,以便LIMIT 将用于切断集合返回函数的输出。

DISTINCT条款

如果指定了 SELECT DISTINCT,则会从结果集中删除所有重复的行(从每组重复项中保留一行)。 SELECT ALL指定相反的方式:保留所有行;这是默认值。

SELECT DISTINCT ON ( expression [, …] )仅保留给定表达式求值的每组行的第一行。使用与 ORDER BY 相同的规则解释DISTINCT ON 表达式(参见上文)。请注意,除非使用 ORDER BY确保首先显示所需的行,否则每个集合的”第一行”都是不可预测的。例如:

SELECT DISTINCT ON (location) location, time, report
    FROM weather_reports
    ORDER BY location, time DESC;

检索每个位置的最新天气报告。但是如果我们没有使用 ORDER BY来强制每个位置的时间值降序,我们就会从每个位置的不可预测的时间得到一份报告。

DISTINCT ON 表达式必须与最左边的 ORDER BY 表达式匹配。 ORDER BY子句通常包含确定每个 DISTINCT ON 组中所需行的优先级的附加表达式。

目前, FOR NO KEY UPDATE , FOR UPDATE ,_ FOR SHARE 和 FOR KEY SHARE无法使用 DISTINCT 指定。

UNION条款

UNION 子句具有以下一般形式:

select_statement UNION [ ALL | DISTINCT ] select_statement

selectstatement 是任何 SELECT 语句,没有 ORDER BY , LIMIT , FOR NO KEY UPDATE , FOR UPDATE , FOR SHARE 或 FOR KEY SHARE 子句。 ( ORDER BY 和 LIMIT 可以附加到子表达式中,如果它括在括号中。没有括号,这些子句将被用于应用于UNION 的结果,而不是它的右侧输入表达式。)

UNION 运算符计算所涉及的 SELECT语句返回的行的集合并集。如果行出现在至少一个结果集中,则行在两个结果集的集合并集中。表示UNION 的直接操作数的两个 SELECT语句必须生成相同数量的列,并且相应的列必须是兼容的数据类型。

除非指定了 ALL 选项,否则 UNION 的结果不包含任何重复行。 ALL可防止删除重复项。 (因此, UNION ALL 通常比 UNION 快得多;尽可能使用 ALL。可以编写 DISTINCT 以明确指定消除重复行的默认行为。除非括号另有说明,否则同一 SELECT 语句中的多个 UNION运算符将从左到右进行计算。

目前,无法为 UNION 结果或 UNION 的任何输入指定 FOR NO KEY UPDATE , FOR UPDATE , FOR SHARE 和 FOR KEY SHARE 。

INTERSECT条款

INTERSECT 子句具有以下一般形式:

select_statement INTERSECT [ ALL | DISTINCT ] select_statement

select_ statement 是没有 ORDER BY , LIMIT ,_ FOR NO KEY UPDATE , FOR UPDATE , FOR SHARE 或 FOR KEY SHARE 子句的任何 SELECT 语句。

INTERSECT 运算符计算返回的行的集合交集所涉及的 SELECT陈述。如果行出现在两个结果集中,则行在两个结果集的交集中。

除非指定了 ALL 选项,否则 INTERSECT 的结果不包含任何重复行。对于 ALL,左表中具有 m 重复项且右表中具有 n 重复项的行将在结果集中显示为min( m, n )次。可以编写 DISTINCT 以显式指定消除重复行的默认行为。

除非括号另有说明,否则同一 SELECT 语句中的多个 INTERSECT运算符将从左到右进行计算。 INTERSECT 绑定比 UNION 更紧密。也就是说, AUNION B INTERSECT C 将被读为 A UNION (B INTERSECT C) 。

目前,无法为 INTERSECT 结果或 INTERSECT 的任何输入指定 FOR NO KEY UPDATE, FOR UPDATE , FOR SHARE 和 FOR KEY SHARE 。

除了条款

EXCEPT 子句具有以下一般形式:

select_statement EXCEPT [ ALL | DISTINCT ] select_statement

select_statement 是没有 ORDER BY , LIMIT , FOR NO KEY UPDATE , FOR UPDATE , FOR SHARE 或 FOR KEY SHARE 子句的任何 SELECT 语句。

EXCEPT 运算符计算左 SELECT 语句结果中的行集,但不计算右行结果中的行集。

除非指定了 ALL 选项,否则 EXCEPT 的结果不包含任何重复行。对于 ALL,左表中具有 m 重复项且右表中具有 n 重复项的行将在结果集中显示max( m -n ,0)次。可以编写 DISTINCT 以显式指定消除重复行的默认行为。

除非括号另有说明,否则同一 SELECT 语句中的多个 EXCEPT运算符将从左到右进行计算。 EXCEPT 与 UNION 处于同一级别。

目前,无法为 EXCEPT 结果或 EXCEPT 的任何输入指定 FOR NO KEY UPDATE ,_FOR UPDATE , FOR SHARE 和 FOR KEY SHARE 。

ORDER BY子句

可选的 ORDER BY 子句具有以下一般形式:

ORDER BY expression [ ASC | DESC | USING operator ] [ NULLS { FIRST | LAST } ] [, ...]

ORDER BY子句导致结果行根据指定的表达式进行排序。如果根据最左边的表达式将两行相等,则根据下一个表达式对它们进行比较,依此类推。如果它们根据所有指定的表达式相等,则它们以依赖于实现的顺序返回。

每个 expression 可以是输出列的名称或序号( SELECT列表项),也可以是由输入列值组成的任意表达式。

序数指的是输出列的序数(从左到右)位置。此功能可以根据没有唯一名称的列定义排序。这绝不是绝对必要的,因为始终可以使用 AS 子句为输出列指定名称。

也可以在 ORDER BY 子句中使用任意表达式,包括未出现在 SELECT输出列表中的列。因此以下声明是有效的:

SELECT name FROM distributors ORDER BY code;

此功能的限制是,应用于 UNION , INTERSECT 或 EXCEPT 子句的结果的 ORDERBY 子句只能指定输出列名称或数字,而不能指定表达式。

如果 ORDER BY 表达式是与输出列名称和输入列名称都匹配的简单名称,则 ORDERBY 会将其解释为输出列名称。这与 GROUP BY 在相同情况下的选择相反。这种不一致性与SQL标准兼容。

可选地,可以在 ORDER BY 子句中的任何表达式之后添加关键字 ASC (升序)或DESC (降序)。如果未指定,则默认采用 ASC 。或者,可以在 USING子句中指定特定的排序运算符名称。排序运算符必须小于或大于某些B树运算符族的成员。ASC 通常相当于 USING < , DESC 通常相当于 USING > 。(但是,用户定义数据类型的创建者可以准确定义默认排序顺序,并且它可能对应于具有其他名称的运算符。)

如果指定了 NULLS LAST ,则空值将在所有非空值之后排序;如果指定了 NULLSFIRST ,则空值将在所有非空值之前排序。如果两者都未指定,则在指定或隐含ASC 时默认行为为 NULLS LAST ;指定 DESC 时为 NULLS FIRST(因此,默认行为为空值大于非空值)。指定 USING时,默认的空值排序取决于运算符是小于还是大于运算符。

请注意,订购选项仅适用于他们遵循的表达式;例如 ORDER BY x, y DESC 与ORDER BY x DESC, y DESC 的含义不同。

字符串数据根据排序规则进行排序适用于要排序的列。可以通过在 expression中包含 COLLATE 子句来重写,例如 ORDER BY mycolumn COLLATE “en_US” 。

LIMIT条款

LIMIT 子句由两个独立的子子句组成:

LIMIT { count | ALL }
OFFSET start

count 指定要返回的最大行数,而 start指定在开始返回行之前要跳过的行数。如果同时指定了两者,则在开始计算要返回的count 行之前会跳过 start 行。

如果 count 表达式的计算结果为NULL,则将其视为 LIMIT ALL ,即无限制。如果start 的计算结果为NULL,则将其视为与 OFFSET 0 相同。

SQL:2008引入了不同的语法来实现相同的结果,Vastbase E100也支持这种结果。它是:

OFFSET start { ROW | ROWS }
FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } ONLY

在此语法中,标准要求 start 或 count值为文字常量,参数说明或变量名称;作为Vastbase E100扩展,允许使用其他表达式,但通常需要将其括在括号中以避免歧义。如果在FETCH 子句中省略 count ,则默认为1. ROW 和 ROWS 以及 FIRST 和 NEXT是不影响这些子句效果的干扰词。根据标准, OFFSET 子句必须在 FETCH子句之前,如果两者都存在;但Vastbase E100很宽松,允许任何一个订单。

使用 LIMIT 时,最好使用 ORDER BY子句将结果行限制为唯一的顺序。否则你会得到一个不可预测的查询行的子集 -你可能会要求第十到第二十行,但第十到第二十行是什么排序?除非指定 ORDERBY ,否则您不知道排序。

生成查询计划时,查询计划程序会将 LIMIT考虑在内,因此您很可能会获得不同的计划(产生不同的行顺序),具体取决于您对LIMIT 和 OFFSET 使用的内容。因此,使用不同的 LIMIT / OFFSET值来选择查询结果的不同子集将产生不一致的结果,除非您使用 ORDER BY强制执行可预测的结果排序。这不是一个bug;除非使用 ORDER BY来约束订单,否则SQL不承诺以任何特定顺序传递查询结果这是事实的固有后果。

如果没有 ORDER BY 强制选择确定性子集,则甚至可能重复执行相同的 LIMIT查询以返回表的行的不同子集。同样,这不是一个错误;在这种情况下,根本无法保证结果的确定性。

锁定条款

FOR UPDATE , FOR NO KEY UPDATE , FOR SHARE 和 FOR KEY SHARE 是锁定条款;它们会影响 SELECT 锁定从表中获取的行。

锁定子句具有一般形式

FOR lock_strength [ OF table_name [, ...] ] [ NOWAIT | SKIP LOCKED ]

其中 lock_strength 可以是其中之一

UPDATE
NO KEY UPDATE
SHARE
KEY SHARE

要防止操作等待其他事务提交,请使用 NOWAIT 或 SKIP LOCKED 选项。对于NOWAIT ,如果无法立即锁定所选行,则语句将报告错误,而不是等待。使用 SKIP LOCKED,将跳过任何无法立即锁定的选定行。跳过锁定的行提供了不一致的数据视图,因此这不适用于通用工作,但可用于避免多个使用者访问类似队列的表的锁争用。请注意,NOWAIT 和 SKIP LOCKED 仅适用于行级锁定 - 所需的 ROW SHARE表级锁定仍以常规方式执行。如果需要获取表级锁定而不等待,则可以先使用带有NOWAIT 选项的 LOCK。

如果在锁定子句中指定了特定表,则只锁定来自这些表的行; SELECT中使用的任何其他表格都可以像往常一样阅读。没有表列表的锁定子句会影响语句中使用的所有表。如果将锁定子句应用于视图或子查询,则会影响视图或子查询中使用的所有表。但是,这些子句不适用于主查询引用的WITH 查询。如果要在 WITH 查询中进行行锁定,请在 WITH查询中指定一个锁定子句。

如果需要为不同的表指定不同的锁定行为,则可以写入多个锁定子句。如果多个锁定子句提到(或隐式地影响)同一个表,则将其处理为好像仅由最强的子句指定。类似地,如果在影响它的任何子句中指定了表,则将其处理为NOWAIT 。否则,如果在影响它的任何子句中指定,则将其处理为 SKIP LOCKED 。

锁定条款不能使用在上下文中,无法使用单个表行清楚地标识返回的行;例如,它们不能与聚合一起使用。

当锁定子句出现在 SELECT查询的顶层时,锁定的行正是查询返回的行;在连接查询的情况下,锁定的行是有助于返回连接行的行。此外,在查询快照中满足查询条件的行将被锁定,但如果在快照之后更新它们并且不再满足查询条件,则不会返回它们。如果使用 LIMIT ,则一旦返回足够的行以满足限制,锁定就会停止(但请注意, OFFSET跳过的行将被锁定)。类似地,如果在游标的查询中使用了锁定子句,则只会锁定光标实际获取或步进的行。

当锁定子句出现在子 SELECT中时,锁定的行是子查询返回到外部查询的行。这可能涉及比单独检查子查询所建议的更少的行,因为来自外部查询的条件可能用于优化子查询的执行。例如,

SELECT * FROM (SELECT * FROM mytable FOR UPDATE) ss WHERE col1 = 5;

将仅锁定具有 col1 = 5 的行,即使该条件在子查询中不是文本上的。

以前的版本无法保留由以后的保存点升级的锁。例如,这段代码:

BEGIN;
SELECT * FROM mytable WHERE key = 1 FOR UPDATE;
SAVEPOINT s;
UPDATE mytable SET ... WHERE key = 1;
ROLLBACK TO s;

在 ROLLBACK TO 之后将无法保留 FOR UPDATE 锁定。这已在9.3版中修复。

注意

SELECT 命令可能在 READ COMMITTED 事务隔离级别运行,并使用 ORDER BY和一个锁定子句无序返回行。这是因为首先应用 ORDER BY。该命令对结果进行排序,但可能会阻止尝试获取一个或多个行的锁定。一旦SELECT解除阻塞,某些排序列值可能已被修改,导致这些行看起来乱序(尽管它们按原始列值排序)。例如,可以通过将FOR UPDATE/SHARE 子句放在子查询中来根据需要解决此问题

SELECT * FROM (SELECT * FROM mytable FOR UPDATE) ss ORDER BY column1;

请注意,这将导致锁定 mytable 的所有行,而顶层的 FOR UPDATE将仅锁定实际返回的行。这可能会产生显着的性能差异,特别是如果 ORDER BY 与LIMIT或其他限制相结合。因此,只有在期望对排序列进行并发更新并且需要严格排序的结果时,才推荐使用此技术。

在 REPEATABLE READ 或 SERIALIZABLE 事务隔离级别,这将导致序列化失败(SQLSTATE 为 '40001' ),因此在这些隔离级别下不可能无序接收行。

TABLE命令

命令

TABLE name

相当于

SELECT * FROM name

它可以在复杂查询的部分中用作顶级命令或节省空间的语法变体。只有 WITH ,UNION , INTERSECT , EXCEPT , ORDER BY , LIMIT , OFFSET , FETCH 和FOR 锁定子句可以与 TABLE 一起使用; WHERE子句和任何形式的聚合都不能使用。

示例

要将表 films 与表 distributors 连接:

SELECT f.title, f.did, d.name, f.date_prod, f.kind
    FROM distributors d, films f
    WHERE f.did = d.did

       title       | did |     name     | date_prod  |   kind
-------------------+-----+--------------+------------+----------
 The Third Man     | 101 | British Lion | 1949-12-23 | Drama
 The African Queen | 101 | British Lion | 1951-08-11 | Romantic
 ...

要对所有电影的列 len 求和,请按 kind对结果进行分组:

SELECT kind, sum(len) AS total FROM films GROUP BY kind;

   kind   | total
----------+-------
 Action   | 07:34
 Comedy   | 02:58
 Drama    | 14:28
 Musical  | 06:42
 Romantic | 04:38

要对所有电影的len列求和、对结果按照 kind分组并且显示总长小于 5 小时的分组:

SELECT kind, sum(len) AS total
    FROM films
    GROUP BY kind
    HAVING sum(len) < interval '5 hours';

   kind   | total
----------+-------
 Comedy   | 02:58
 Romantic | 04:38

以下两个示例是根据第二列( name )的内容对各个结果进行排序的相同方法:

SELECT * FROM distributors ORDER BY name;
SELECT * FROM distributors ORDER BY 2;

 did |       name
-----+------------------
 109 | 20th Century Fox
 110 | Bavaria Atelier
 101 | British Lion
 107 | Columbia
 102 | Jean Luc Godard
 113 | Luso films
 104 | Mosfilm
 103 | Paramount
 106 | Toho
 105 | United Artists
 111 | Walt Disney
 112 | Warner Bros.
 108 | Westward

下一个示例显示如何获取表 distributors 和 actors的并集,将结果限制为每个表中以字母W开头的结果。只需要不同的行,因此省略关键字ALL 。

distributors:               actors:
 did |     name              id |     name
-----+--------------        ----+----------------
 108 | Westward               1 | Woody Allen
 111 | Walt Disney            2 | Warren Beatty
 112 | Warner Bros.           3 | Walter Matthau
 ...                         ...

SELECT distributors.name
    FROM distributors
    WHERE distributors.name LIKE 'W%'
UNION
SELECT actors.name
    FROM actors
    WHERE actors.name LIKE 'W%';

      name
----------------
 Walt Disney
 Walter Matthau
 Warner Bros.
 Warren Beatty
 Westward
 Woody Allen

此示例显示如何使用 FROM 子句中的函数,包括和不包含列定义列表:

CREATE FUNCTION distributors(int) RETURNS SETOF distributors AS $$
    SELECT * FROM distributors WHERE did = $1;
$$ LANGUAGE SQL;

SELECT * FROM distributors(111);
 did |    name
-----+-------------
 111 | Walt Disney

CREATE FUNCTION distributors_2(int) RETURNS SETOF record AS $$
    SELECT * FROM distributors WHERE did = $1;
$$ LANGUAGE SQL;

SELECT * FROM distributors_2(111) AS (f1 int, f2 text);
 f1  |     f2
-----+-------------
 111 | Walt Disney

以下是添加了常规列的函数示例:

SELECT * FROM unnest(ARRAY['a','b','c','d','e','f']) WITH ORDINALITY;
 unnest | ordinality
--------+----------
 a      |        1
 b      |        2
 c      |        3
 d      |        4
 e      |        5
 f      |        6
(6 rows)

此示例显示如何使用简单的 WITH 子句:

WITH t AS (
    SELECT random() as x FROM generate_series(1, 3)
  )
SELECT * FROM t
UNION ALL
SELECT * FROM t

         x          
--------------------
  0.534150459803641
  0.520092216785997
 0.0735620250925422
  0.534150459803641
  0.520092216785997
 0.0735620250925422

请注意, WITH 查询仅评估一次,因此我们得到两组相同的三个随机值。

此示例使用 WITH RECURSIVE从仅显示直接下属的表中查找员工Mary的所有下属(直接或间接)及其间接级别:

WITH RECURSIVE employee_recursive(distance, employee_name, manager_name) AS (
    SELECT 1, employee_name, manager_name
    FROM employee
    WHERE manager_name = 'Mary'
  UNION ALL
    SELECT er.distance + 1, e.employee_name, e.manager_name
    FROM employee_recursive er, employee e
    WHERE er.employee_name = e.manager_name
  )
SELECT distance, employee_name FROM employee_recursive;

请注意递归查询的典型形式:初始条件,后跟 UNION,后跟查询的递归部分。确保查询的递归部分最终不返回任何元组,否则查询将无限循环。此示例使用 LATERAL 为 manufacturers 的每一行应用一组返回函数get_product_names() 表:

SELECT m.name AS mname, pname
FROM manufacturers m, LATERAL get_product_names(m.id) pname;

目前没有任何产品的制造商不会出现在结果中,因为它是内部联接。如果我们希望在结果中包含此类制造商的名称,我们可以:

SELECT m.name AS mname, pname
FROM manufacturers m LEFT JOIN LATERAL get_product_names(m.id) pname ON true;

兼容性

当然, SELECT 语句与SQL标准兼容。但是有一些扩展和一些缺失的功能。

从条款中省略

Vastbase E100允许一个省略 FROM子句。它可以直接用于计算简单表达式的结果:

SELECT 2+2;

 ?column?
----------
        4

其他一些SQL数据库不能这样做,除非引入一个虚拟的单行表来执行 SELECT 。

请注意,如果未指定 FROM子句,则查询无法引用任何数据库表。例如,以下查询无效:

SELECT distributors.* WHERE distributors.name = 'Westward';
清空SELECT列表

SELECT之后的输出表达式列表可以为空,从而生成零列结果表。根据SQL标准,这不是有效的语法。Vastbase E100允许它与允许零列表一致。但是,使用 DISTINCT时,不允许使用空列表。

省略AS关键字

在SQL标准中,只要新列名是有效列名(即,与任何保留关键字不同),就可以在输出列名之前省略可选关键字AS 。 Vastbase E100稍微有点限制:如果新列名完全匹配任何关键字,保留与否,则需要 AS。建议的做法是使用 AS或双引号输出列名称,以防止与将来添加关键字的任何可能冲突。

在 FROM 项中,标准和Vastbase E100都允许在作为非保留关键字的别名之前省略AS 。但由于语法含糊不清,这对输出列名称来说是不切实际的。

ONLY和继承

编写 ONLY 时,SQL标准需要围绕表名括号,例如 SELECT * FROM ONLY (tab1),ONLY (tab2) WHERE … 。 Vastbase E100认为这些括号是可选的。

Vastbase E100允许写入尾随 * 以显式指定包含子表的非 ONLY行为。该标准不允许这样做。

(这些要点同样适用于支持 ONLY 选项的所有SQL命令。)

TABLESAMPLE条款限制

TABLESAMPLE子句目前仅在常规表和物化视图中被接受。根据SQL标准,应该可以将它应用于任何FROM 项目。

函数调用FROM

Vastbase E100允许函数调用直接作为 FROM列表的成员编写。在SQL标准中,有必要将这样的函数调用包装在子_1128253中;也就是说,语法FROM func(…) alias 大致相当于 FROM LATERAL (SELECT func(…)) alias。注意 LATERAL 被认为是隐含的;这是因为该标准要求 FROM 中的 UNNEST()项目具有 LATERAL 语义。 Vastbase E100将 UNNEST()视为与其他set-returns函数相同。

命名空间可用于GROUP BY和ORDER BY

在SQL-92标准中, ORDER BY 子句只能使用输出列名或数字,而 GROUP BY子句只能使用基于输入列名的表达式。 Vastbase E100扩展了这些子句中的每一个以允许其他选择(但如果存在歧义,它会使用标准的解释)。Vastbase E100还允许两个子句指定任意表达式。请注意,表达式中出现的名称将始终作为输入列名称,而不是输出列名称。

SQL:1999及更高版本使用稍微不同的定义,它与SQL-92不完全向上兼容。但是,在大多数情况下,Vastbase E100将以与SQL:1999相同的方式解释 ORDER BY 或 GROUP BY 表达式。

功能依赖项

只有当表的主键包含在 GROUP BY 列表中时,Vastbase E100才会识别函数依赖(允许从 GROUP BY 中省略列)。SQL标准指定了应该识别的附加条件。

LIMIT和OFFSET

子句 LIMIT 和 OFFSET 是Vastbase E100特定的语法,也被MySQL使用。SQL:2008标准引入了相同功能的子句 OFFSET … FETCH {FIRST|NEXT} …,如上面 LIMIT Clause所示。 IBM DB2也使用此语法。(为Oracle编写的应用程序经常使用涉及自动生成的 rownum列的解决方法,该列在Vastbase E100中不可用,以实现这些子句的效果。)

FOR NO KEY UPDATE,FOR UPDATE,FOR SHARE,FOR KEY SHARE

尽管 FOR UPDATE 出现在SQL标准中,但该标准仅允许它作为 DECLARE CURSOR的选项。 Vastbase E100允许它在任何 SELECT 查询以及子 SELECT中,但这是一个扩展名。 FOR NO KEY UPDATE , FOR SHARE 和 FOR KEY SHARE变体以及 NOWAIT 和 SKIP LOCKED 选项未出现在标准中。

WITH中的数据修改语句

Vastbase E100允许 INSERT , UPDATE 和 DELETE 用作 WITH查询。这在SQL标准中找不到。

非标准条款

DISTINCT ON ( … ) 是SQL标准的扩展。

ROWS FROM( … ) 是SQL标准的扩展。