第二章 SQL命令参考-SELECT

来源:互联网 发布:淘宝视频链接地址 编辑:程序博客网 时间:2024/06/04 19:57

SELECT

Retrieves rowsfrom a table or view.

概要

 

SELECT[ALL | DISTINCT [ON (expression [, ...])]]

* |expression [[AS] output_name] [, ...]

[FROMfrom_item [, ...]]

[WHEREcondition]

[GROUPBY grouping_element [, ...]]

[HAVINGcondition [, ...]]

[WINDOWwindow_name AS (window_specification)]

[{UNION| INTERSECT | EXCEPT} [ALL] select]

[ORDERBY expression [ASC | DESC | USING operator] [, ...]]

[LIMIT{count | ALL}]

[OFFSETstart]

[FOR{UPDATE | SHARE} [OF table_name [, ...]] [NOWAIT] [...]]

 

wheregrouping_element can be one of:

 

 

expression

ROLLUP(expression [,...])

CUBE (expression[,...])

GROUPINGSETS ((grouping_element [, ...]))

 

wherewindow_specification can be:

 

[window_name]

[PARTITIONBY expression [, ...]]

[ORDERBY expression [ASC | DESC | USING operator] [, ...]

[{RANGE| ROWS}

{UNBOUNDED PRECEDING

|expression PRECEDING

|CURRENT ROW

|BETWEEN window_frame_bound AND window_frame_bound }]]

wherewindow_frame_bound can be one of:

UNBOUNDEDPRECEDING

expression PRECEDING

CURRENTROW

expression FOLLOWING

UNBOUNDEDFOLLOWING

 

wherefrom_item can be one of:

 

[ONLY]table_name [[AS] alias [( column_alias [, ...] )]]

(select)[AS] alias [( column_alias [, ...] )]

function_name ( [argument [, ...]] ) [AS] alias

[(column_alias [, ...]

|column_definition [, ...] )]

function_name ( [argument [, ...]] ) AS

(column_definition [, ...] )

from_item [NATURAL] join_type from_item

[ONjoin_condition | USING ( join_column [, ...] )]

 

 

描述

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

2.如果指定了WHERE子句,不满足的条件的所有行被从输出消除。

3.如果指定GROUP BY子句,输出被分成匹配的一个或多个定义的分组的元素的行组。如果HAVING子句存在,它消除了不符合给定条件组。

4.如果指定一个窗口的表达(以及可选的WINDOW子句),输出根据该位置(行)组织或基于值的(范围)窗框。

5. DISTINCT从结果重复的行。 DISTINCT ON消除匹配所有指定表达式的行。 ALL(缺省)将返回所有候选行,包括重复的。

6.实际输出行使用每个选定行SELECT输出表达式来计算。

7.使用运算符UNION,相交,并除,多于一个SELECT语句的输出可以被组合以形成一个单_的结果集。 UNION操作符返回在一个或两个结果集的所有行。 INTERSECT运算符返回严格在这两个结果集的所有行。 EXCEPT运算符返回在设置,但不是在第二的第一个结果行。在这三种情况下,除非指定ALL删除重复的行。

8.如果指定了ORDER BY子句,返回的行会按照指定的顺序排序。如果没有给出ORDER BY,该行可以以任意顺序系统找到最快的生产恢复。

9.如果指定了LIMIT或OFFSET子句,SELECT语句只返回结果行的一个子集。

10.如果FOR UPDATE或FOR SHARE指定,SELECT语句对锁定并发更新整个表。

你必须有一个表的SELECT权限才能读取它的值。使用FOR UPDATE或FOR SHARE要求UPDATE权限。

parameter

The SELECT List

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

使用子句[AS]output_name,可以为输出列指定另一个名称。此名称主要用于标记列以供显示。它也可以用于引用ORDER BY和GROUP BY子句中的列的值,但不能在WHERE或HAVING子句中引用;那你必须写出这个表达。在大多数情况下,AS关键字是可选的(例如在声明列名称,常量,函数调用和简单的一元运算符表达式的别名时)。在声明的别名是保留的SQL关键字的情况下,output_name必须用双引号括起来,以避免歧义。

SELECT列表中的表达式可以是常量值,列引用,运算符调用,函数调用,聚合表达式,窗口表达式,标量子查询等。许多构造可以被分类为表达式,但不遵循任何一般的语法规则。这些通常具有函数或运算符的语义。有关SQL值表达式和函数调用的信息,请参阅“Greenplum数据库管理员指南”中的“查询数据”。

The FROM Clause

FROM子句为SELECT指定一个或多个源表。 如果指定了多个源,则结果是所有源的笛卡尔乘积(交叉连接)。 但是通常添加限定条件以将返回的行限制为笛卡尔乘积的一小部分。 FROM子句可以包含以下元素:

 

table_name

现有表或视图的名称(可选模式限定)。如果指定了ONLY,则仅扫描该表。如果未指定ONLY,则扫描该表及其所有后代表(如果有)。

alias

包含别名的FROM项的替代名称。为了简洁起见使用一个别名,或消除自连接的歧义(多次扫描同一张表)。当提供别名时,它完全隐藏表或函数的实际名称;例如给出FROM foo AS f,其余的SELECT必须将此FROM项引用为f not foo。如果写入别名,也可以写入列别名列表来为表的一个或多个列提供替代名称。

select

一个sub-sELECT可以出现在FROM子句中。这个行为就好像在单个SELECT命令的持续时间内将其输出创建为临时表。请注意,子选项必须用括号括起来,并且必须为其提供别名。此处也可以使用VALUES命令。有关在Greenplum数据库中使用相关子选项的限制,请参阅兼容性部分中的“非标准条款”。

function_name

函数调用可以出现在FROM子句中。 (这对于返回结果集的函数特别有用,但是可以使用任何函数)。这个行为就好像在单个SELECT命令的持续时间内将其输出创建为临时表。 也可以使用别名。 如果写入别名,还可以编写列别名列表来为函数的复合返回类型的一个或多个属性提供替代名称。 如果函数定义为返回记录数据类型,则必须存在别名或关键字AS,后跟列表定义列表(coiumn_namedata_type [,...])。 列定义列表必须与函数返回的列的实际数量和类型相匹配。

join_type

One of:

•    [INNER] JOIN

•    LEFT [OUTER]JOIN

•    RIGHT [OUTER]JOIN

•    FULL [OUTER]JOIN

•    CROSS JOIN

对于INNER和OUTER连接类型,必须指定连接条件,即NATURAL,ONjoin_condition或USING([,...])中的一个。见下文

含义。对于CROSS JOIN,这些条款都不会出现。

 

JOIN子句组合了两个FROM项。如有必要,请使用括号确定嵌套的顺序。在没有括号的情况下,JOINS从左到右嵌套。在任何情况下,JOIN比分隔FROM项的逗号更紧。

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返回所有连接的行,对于每个不匹配的左侧行(用右侧的空值进行扩展),再加上一行,每行不匹配的右侧行加上一行(左侧为null)。

 

ON join_condition

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

USING (join_column [,...])

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

NATURAL

NATURAL是USING列表的缩写,它提到两个表中具有相同名称的所有列。

The WHERE Clause

可选的WHERE子句具有以下通用格式:

WHERE condition

where condition是任何表达式,其计算结果为boolean类型。任何不满足此条件的行将从输出中消除。如果实际行值代替任何变量引用,则该行满足条件。

The GROUP BY Clause

可选的GROUP BY子句具有以下通用格式:

GROUP BY grouping_element [,...]

where grouping_element can be one of:

()

expression

ROLLUP (expression [,...])

CUBE (expression [,...])

GROUPING SETS ((grouping—element [,...]))

GROUP BY将会将所有选定的行集合到单个行中,这些行对于分组的表达式共享相同的值。表达式可以是输入列名称,或输出列(SELECT list item)的名称或序数,也可以是从输入列值形成的任意表达式。在歧义的情况下,GROUP BY名称将被解释为输入列名称,而不是输出列名称。

使用聚合函数(如果有的话)在组成每个组的所有行中计算,为每个组生成一个单独的值(而不使用GROUP BY,则聚合将生成在所有选定行中计算的单个值)。当GROUP BY存在时,对于SELECT列表表达式,除了聚合函数之外,不能引用未分组的列,因为对于未分组的列将返回多个可能的值。

Greenplum数据库具有以下附加的OLAP分组扩展(通常称为超组):

 

ROLLUP

ROLLUP分组是GROUP BY子句的扩展,它创建从最详细级别到总计的汇总小计,遵循分组列(或表达式)列表。 ROLLUP采用分组列的有序列表,计算GROUP BY子句中指定的标准聚合值,然后创建逐级更高级别

小计从右到左从列表中移动。最后,它创造了一个总计。 ROLLUP分组可以被认为是一系列分组集合。例如:

GROUP BYROLLUP (a,b,c)

is equivalentto:

GROUP BY GROUPING SETS( (a,b,c),(a,b),(a),())

请注意,ROLLUP的n个元素转换为n + 1个分组集。此外,在ROLLUP中指定分组表达式的顺序很重要。

CUBE

CUBE分组是GROUP BY子句的扩展,它为给定的分组列(或表达式)列表的所有可能组合创建小计。在多维分析方面,CUBE生成可以为具有指定维度的数据多维数据集计算的所有小计。例如:

GROUP BY CUBE(a,b,c)

is equivalentto:

GROUP BY GROUPING SETS((a,b,c),(a,b),(a,c),(b,c),(a),

(b),(c),())

请注意,CUBE的n个元素转换为2n个分组集。考虑在任何需要交叉表格报告的情况下使用CUBE。 CUBE通常最适合使用来自多个维度的列而不是表示单个维度的不同级别的列的查询。例如,通常要求的交叉表可能需要用于月,州和产品的所有组合的小计。

GROUPING SETS

您可以使用GROUP BY子句中的GROUPING SETS表达式有选择地指定要创建的组集。这允许跨多个维度的精确规范,而不需要计算整个ROLLUP或CUBE。例如:

GROUP BY GROUPING SETS( (a,c),(a,b))

如果使用分组扩展子句ROLLUP,CUBE或GROUPING SETS,则会出现两个挑战。首先,您如何确定哪些结果行是小计,然后确定给定小计的确切级别。或者,如何区分包含存储的NULL值和由ROLLUP或CUBE创建的“NULL”值的结果行。其次,当在GROUP BY子句中指定重复的分组集合时,如何确定哪些结果行是重复的?您可以在SELECT列表中使用两个额外的分组功能来帮助您:

 grouping(column[, ...]) — The grouping function can be applied to one or moregrouping attributes to distinguish super-aggregated rows from regular groupedrows.

分组函数可以应用于一个或多个分组属性,以将超级聚合行与常规分组行区分开来。

这可以有助于将表示超级聚合行中的所有值的集合的“NULL”与常规行中的NULL值区分开。此函数中的每个参数产生一个位 - 1或0,其中1表示结果行是超级聚合,0表示结果行来自常规分组。分组函数通过将这些位视为二进制数返回一个整数,然后将其转换为基10整数。

group_id() — 对于包含重复分组集的扩展查询分组,group_id函数用于标识输出中的重复行。所有唯一的分组集输出行的group_id值为0.对于检测到的每个重复分组集,group_id函数分配大于0的group_id数。特定重复分组集中的所有输出行由相同的group_id号标识。

The WINDOW Clause

The window clause is used to define a window thatcan be used in the over() expression of a window function such as rank or avg. For example:

SELECT vendor,rank() OVER (mywindow) FROM sale GROUP BY vendor

WINDOW mywindow AS (ORDER BYsum(prc*qty));

A window clause has this general form:

WINDOW window_name AS (window_specification)

where window_speciflcation can be:

[window_name]

[PARTITION BY expression [,...]]

[ORDER BY expression [ASC | DESC | USING operator][,...]

[{RANGE |ROWS}

{ UNBOUNDEDPRECEDING | expression PRECEDING | CURRENT ROW

| BETWEENAND win}]]

where window_frame_bound can be one of:

unboundedPreceding

expression PRECEDING CURRENT ROW expression FOLLOWING UNBOUNDED FOLLOWING

window_name

给出窗口规范的名称。

PARTITION BY

PARTITION BY子句根据指定表达式的唯一值将结果集合组织成逻辑组。当与窗口功能一起使用时,功能将独立应用于每个分区。例如,如果您使用列名称跟随PARTITIONBY,则结果集将被该列的不同值分隔。如果省略,整个结果集被认为是一个分区。

ORDER BY

ORDER BY子句定义了如何对结果集的每个分区中的行进行排序。如果省略,行以任何顺序返回最有效,可能会有所不同。注意:缺少一致的排序(如时间)的数据类型列不适用于窗口规范的ORDER BY子句。时间有或没有时区,缺少一致的排序,因为加法和减法没有预期的效果。例如,以下几乎不是真的For example, the following is notgenerally true: x::time < x::time + '2hour'::interval

ROWS | RANGE

使用ROWS或RANGE子句来表达窗口的边界。绑定的窗口可以是分区的一个,多个或所有行。您可以根据从当前行(RANGE)中的值偏移的数据值范围,或以与当前行(ROWS)偏移的行数来表示窗口的边界。使用RANGE子句时,还必须使用ORDER BY子句。这是因为为了生成窗口而执行的计算需要对值进行排序。此外,ORDER BY子句不能包含多个表达式,并且表达式必须导致日期或数值。当使用ROWS或RANGE子句时,如果仅指定起始行,则当前行将用作窗口中的最后一行。

PRECEDING —PRECEDING子句使用当前行作为参考点定义窗口的第一行。起始行以当前行之前的行数表示。例如,在ROWS成帧的情况下,5 PRECEDING将窗口设置为从当前行之前的第五行开始。在RANGE成帧的情况下,它将窗口从给定顺序的排序列值先于当前行的第一行开始。如果指定的订单按日期升序,这将是当前行前5天内的第一行。 UNBOUNDED PRECEDING将窗口中的第一行设置为分区中的第一行。

BETWEEN —BETWEEN子句定义窗口的第一行和最后一行,使用当前行作为参考点。第一行和最后一行分别以当前行之前和之后的行数表示。例如,BETWEEN 3 PRECEDING AND 5 FOLLOWING将窗口设置为从当前行之前的第三行开始,并以当前行之后的第五行结束。使用下面的未加掩饰的前缀和无关键的方式将窗口中的第一行和最后一行分别设置为分区的第一行和最后一行。如果没有指定ROW或RANGE子句,则这相当于默认行为。

FOLLOWING —FOLLOWING子句使用当前行作为参考点定义窗口的最后一行。最后一行用当前行后面的行数表示。例如,在ROWS成帧的情况下,5 FOLLOWING将窗口设置为以当前行之后的第五行结束。在RANGE成帧的情况下,它将窗口设置为结束,其最后一行的排序列值按照给定的顺序按当前行的顺序排列5。如果指定的订单按日期升序,这将是当前行后5天内的最后一行。使用UNBOUNDEDFOLLOWING将窗口中的最后一行设置为分区中的最后一行。

如果没有指定ROW或RANGE子句,则边界从分区(UNBOUNDEDPRECEDING)中的第一行开始,如果使用ORDER BY,则以当前行(CURRENT ROW)结束。如果未指定ORDER BY,则窗口从分区中的第一行开始

(UNBOUNDED PRECEDING)并以分区中的最后一行结束(UNBOUNDED FOLLOWING)。

The HAVINGClause

The optional having clause hasthe general form:

HAVING condition

where条件与WHERE子句指定的条件相同。 HAVING消除了不满足条件的组行。 HAVING不同于WHERE:WHERE在GROUP BY应用程序之前过滤单个行,而HAVING过滤GROUP BY创建的组行。 条件中引用的每个列必须明确地引用分组列,除非引用出现在聚合函数中。

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

The UNION Clause

The union clause has this general form:

select_statement UNION [ALL] select_statement

 

其中select_statement是没有ORDER BY,LIMIT,FORUPDATE或FOR SHARE子句的任何SELECT语句。 (ORDER BY和LIMIT可以附加到子查询表达式,如果它被括在括号中。

没有括号,这些条款将被用来适用于联盟的结果,而不是右边的输入表达式。)

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

 

The INTERSECTClause

INTERSECT条款具有以下一般形式:

select_statement INTERSECT[ALL] select_statement其中select_statement是没有ORDER BY,LIMIT,FOR UPDATE或FOR SHARE子句的任何SELECT语句。

INTERSECT运算符计算相关SELECT语句返回的行的集合交集。 如果两个结果集都出现在两个结果集的交集中,那么它就是一行。

INTERSECT的结果不包含任何重复行,除非指定了ALL选项。使用ALL,在左表中有m个重复的行,右表中的n个重复行将在结果集中显示min(m,n)次。

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

目前,对于INTERSECT结果或INTERSECT的任何输入,不得指定FORUPDATE和FOR SHARE。

The EXCEPT Clause

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

select_statement EXCEPT [ALL]select_statement其中select_statement是没有ORDER BY,LIMIT,FOR UPDATE或FOR SHARE的任何SELECT语句

条款。

EXCEPT运算符计算左侧SELECT语句的结果中的行集合,而不是在右侧的结果中计算。

EXCEPT的结果不包含任何重复行,除非指定了ALL选项。 使用ALL,在左表中有m个重复行,右表中的n个重复行将在结果集中显示max(m-n,0)次。

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

目前,对于EXCEPT结果或EXCEPT的任何输入,可能不会指定FOR UPDATE和FORSHARE。

The ORDER BYClause

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

ORDER BY表达式[ASC | DESC |使用运算符] [,...]

其中表达式可以是输出列(SELECT列表项)的名称或序数,也可以是

从输入列值形成的任意表达式ORDER BY子句使结果行按照指定的表达式进行排序。如果根据最左边的表达式两行相等,则根据下一个表达式进行比较,依此类推。如果它们根据所有指定的表达式相等,则以依赖于实现的顺序返回。

序数是指结果列的顺序(从左到右)的位置。此功能使得可以根据不具有唯一名称的列来定义排序。这从来没有

绝对必要,因为总是可以使用AS子句为结果列分配名称。

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

SELECT名称来自经销商ORDER BY代码;

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

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

可选地,可以在ORDER BY子句中的任何表达式之后添加关键字ASC(升序)或DESC(降序)。如果未指定,则默认情况下采用ASC。或者,可以在USING子句中指定特定的排序运算符名称。ASC通常相当于USING <和DESC通常

相当于USING>。 (但用户定义的数据类型的创建者可以准确定义默认排序顺序,并且可能与具有其他名称的运算符相对应)

空值排序高于任何其他值。换句话说,按照排序顺序排序,空值排序在最后,并且按照排序顺序排序,空值开头排序。

字符串数据根据Greenplum数据库系统初始化时建立的特定于区域的归类顺序进行排序。

 

The DISTINCT Clause

 

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

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

 

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

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

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

当Greenplum数据库处理包含DISTINCT子句的查询时,查询将转换为GROUPBY查询。在许多情况下,转型提供了显着的性能提升。然而,当不同值的数量接近总行数时,转换可能导致生成多级分组计划。在这种情况下,由于较低聚合级别引入的开销,存在预期的性能下降。

 

The LIMITClause

The limit clause consists of two independentsub-clauses:

LIMIT {count | ALL}

OFFSET start

其中count指定要返回的最大行数,而start指定在开始返回行之前要跳过的行数。当指定两者时,在开始计数要返回的计数行之前,将跳过开始行。

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

查询优化器在生成查询计划时会考虑LIMIT,因此根据用于LIMIT和OFFSET的内容,您很可能会获得不同的计划(产生不同的行顺序)。因此,使用不同的LIMIT /OFFSET值来选择查询结果的不同子集将导致不一致的结果,除非您使用ORDER BY强制执行可预期的结果排序。这不是缺点;这是事实的固有后果,SQL不承诺以任何特定的顺序传递查询的结果,除非使用ORDER BY来约束顺序。

FOR UPDATE/ FOR SHARE子句

FOR UPDATE子句具有这种形式:

FOR UPDATE[表名[,...]] [NOWAIT]

密切相关的FOR SHARE子句具有这种形式:

分享[表格名称[,...]] [NOWAIT]

FOR UPDATE导致SELECT语句访问的表被锁定,就像更新一样。

这可以防止表格被其他事务修改或删除,直到当前事务结束。也就是说,其他事务试图UPDATE,DELETE或SELECT FORUPDATE这个表将被阻塞,直到当前事务结束。此外,如果另一个事务的UPDATE,DELETE或SELECT FORUPDATE已经锁定了选定的表,SELECT FORUPDATE将等待另一个事务完成,然后锁定并返回更新的表。

为防止操作等待其他事务提交,请使用NOWAIT选项。 SELECT FORUPDATE NOWAIT报告错误,而不是等待,如果选定的行不能立即被锁定。请注意,NOWAIT仅适用于行级锁.⑶所需的ROW SHARE表级锁仍然是以普通的方式进行的。如果您需要无需等待而获取表级锁,则可以使用LOCK的NOWAIT选项(请参见LOCK)。

FOR SHARE的行为类似,除了获取表上的共享锁而不是独占锁。共享锁可阻止其他事务在表上执行UPDATE,DELETE或SELECT FORUPDATE,但不妨碍它们执行SELECT FORSHARE。

如果在FOR UPDATE或FOR SHARE中指定了特定的表,那么只有这些表被锁定;在SELECT中使用的任何其他表格都照常阅读。没有表列表的FOR UPDATE或FOR SHARE子句会影响命令中使用的所有表。如果FOR UPDATE或FOR SHARE应用于视图或子查询,则会影响视图或子查询中使用的所有表。

如果需要为不同的表指定不同的锁定行为,则可以写入多个FOR UPDATE和FOR SHARE子句。如果FOR UPDATE和FOR SHARE子句提及(或隐式影响)相同的表,则将其作为FOR UPDATE进行处理。同样,如果在影响它的任何子句中指定了一个表,则该表被处理为NOWAIT。

示例

    将films表和distributors进行关联:

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

获得length的总和,并按照kind进行分组:

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

获得length的总和,并按照kind进行分组,并且总时长小于5小时:

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

 

计算电影种类和分销商的所有销售小计和总计。

SELECT kind,distributor,sum(prc * qty)FROMsales GROUP BY ROLLUP(kind,distributor)

ORDER BY 1,2,3;

根据总销售额计算电影发行商的排名:

SELECTdistributor, sum(prc*qty),

rank() OVER(ORDER BY sum(prc*qty) DESC)

FROM sale

GROUP BYdistributor ORDER BY 2 DESC;

 

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

SELECT  FROM    distributors    ORDER   BYname;

SELECT  FROM    distributors    ORDER   BY2;

 

下一个示例显示如何获得表分销商和参与者的联合,将结果限制为每个表中以字母W开头的结果。只需要不同的行,所以省略关键字ALL:

SELECTdistributors.name FROM distributors WHERE distributors.name LIKE 'W%' UNIONSELECT actors.name FROM actors WHERE actors.name LIKE 'W%';

 

这个例子展示了如何在FROM子句中使用一个函数,无论是否有列定义列表:

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

SELECT * FROMdistributors(111);

CREATE FUNCTIONdistributors_2(int) RETURNS SETOF record AS $$ SELECT * FROM distributors WHEREdid = $1; $$ LANGUAGE SQL;

SELECT * FROMdistributors_2(111) AS (dist_id int, dist_name text);

兼容性

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

省略FROM子句

Greenplum数据库允许你省略FROM子句。它有一个简单的用法来计算简单表达式的结果。例如:

SELECT2 + 2;

一些其他的SQL数据库不能做到这一点,除了引入一个虚拟的单行表从中做

SELECT。

请注意,如果未指定FROM子句,则查询不能引用任何数据库表。对于依赖此行为的应用程序兼容性,可以启用add_missing_from配置变量。

AS关键字

在SQL标准中,可选关键字AS只是噪声,在不影响意义的情况下可以省略。 Greenplum数据库解析器在重新命名输出列时需要这个关键字,因为类型的可扩展性特性导致在没有它的情况下解析歧义。但是,在FROM项目中,AS是可选的。

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

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

SQL:1999和更高版本使用一个稍微不同的定义,它不完全向上兼容SQL-92。然而,在大多数情况下,Greenplum数据库将以与SQL:1999相同的方式解释ORDERBY或GROUP BY表达式。

非标准条款

SQL标准中没有定义DISTINCT ON,LIMIT和OFFSET子句。

有限的使用稳定和挥发功能

为了防止数据在Greenplum数据库中的段之间不同步,任何分类为STABLE或VOLATILE的函数如果包含SQL或以任何方式修改数据库,则不能在段数据库级别执行。有关更多信息,请参阅CREATE FUNCTION。

相关参考

EXPLAIN