# 选择
SELECT, TABLE, WITH — 从表或视图中检索行
# 概要
[ WITH [ RECURSIVE ] with_query [, ...] ]
SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ]
[ * | expression [ [ AS ] output_name ] [, ...] ]
[ FROM from_item [, ...] ]
[ WHERE condition ]
[ GROUP BY [ ALL | DISTINCT ] 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 | WITH TIES } ]
[ FOR { UPDATE | NO KEY UPDATE | SHARE | KEY SHARE } [ OF table_name [, ...] ] [ NOWAIT | SKIP LOCKED ] [...] ]
where from_item can be one of:
[ 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 [, ...] ) [ AS join_using_alias ] ]
and grouping_element can be one of:
( )
expression
( expression [, ...] )
ROLLUP ( { expression | ( expression [, ...] ) } [, ...] )
CUBE ( { expression | ( expression [, ...] ) } [, ...] )
GROUPING SETS ( grouping_element [, ...] )
and with_query is:
with_query_name [ ( column_name [, ...] ) ] AS [ [ NOT ] MATERIALIZED ] ( select | values | insert | update | delete )
[ SEARCH { BREADTH | DEPTH } FIRST BY column_name [, ...] SET search_seq_col_name ]
[ CYCLE column_name [, ...] SET cycle_mark_col_name [ TO cycle_mark_value DEFAULT cycle_mark_default ] USING cycle_path_col_name ]
TABLE [ ONLY ] table_name [ * ]
# 描述
选择
从零个或多个表中检索行。一般处理选择
如下:
中的所有查询
和
计算列表。这些有效地充当临时表,可以在从
列表。一种和
中多次引用的查询从
只计算一次,除非另有说明未物化
.(看WITH 子句以下。)中的所有元素
从
计算列表。(每个元素在从
list 是一个真实的或虚拟的表。)如果在从
列表,它们交叉连接在一起。(看从子句以下。)如果
在哪里
子句时,所有不满足条件的行都会从输出中剔除。(看WHERE 子句以下。)如果
通过...分组
子句被指定,或者如果有聚合函数调用,则将输出组合成与一个或多个值匹配的行组,并计算聚合函数的结果。如果拥有
子句存在时,它会消除不满足给定条件的组。(看GROUP BY 条款和有条款以下。)实际输出行是使用
选择
每个选定行或行组的输出表达式。(看选择列表以下。)选择不同的
从结果中消除重复行。选择不同
消除与所有指定表达式匹配的行。全选
(默认)将返回所有候选行,包括重复行。(看区别条款以下。)使用运算符
联盟
,相交
, 和除了
, 一个以上的输出选择
语句可以组合形成单个结果集。这联盟
运算符返回一个或两个结果集中的所有行。这相交
运算符返回严格在两个结果集中的所有行。这除了
运算符返回第一个结果集中但不在第二个结果集中的行。在所有三种情况下,重复行都被消除,除非全部
被指定。噪音词清楚的
可以添加以明确指定消除重复行。请注意清楚的
是这里的默认行为,即使全部
是默认的选择
本身。(看联合条款,相交条款, 和除外条款以下。)如果
订购方式
子句时,返回的行按指定的顺序排序。如果订购方式
未给出,则以系统发现最快生成的任何顺序返回行。(看ORDER BY 条款以下。)如果
限制
(或者先取
) 或者抵消
条款被指定,则选择
语句只返回结果行的子集。(看限制条款以下。)如果
更新
,无密钥更新
,分享
或者关键分享
被指定,选择
语句锁定选定的行以防止并发更新。(看锁定条款以下。)你必须有
选择
对 a 中使用的每一列的权限选择
命令。指某东西的用途无密钥更新
,更新
,分享
或者关键分享
需要更新
特权(对于如此选择的每个表的至少一列)。
# 参数
# 和
条款
这和
子句允许您指定一个或多个子查询,这些子查询可以在主查询中按名称引用。在主查询期间,子查询有效地充当临时表或视图。每个子查询可以是选择
,桌子
,价值观
,插入
,更新
或者删除
陈述。编写数据修改语句时(插入
,更新
要么删除
) 在和
,通常包括一个返回
条款。这是输出返回
,不是该语句修改的基础表,它形成了由主查询读取的临时表。如果返回
省略时,该语句仍会执行,但它不会产生任何输出,因此主查询不能将其作为表引用。
必须为每个指定名称(无模式限定)和
询问。可选地,可以指定列名列表;如果省略,则从子查询中推断列名。
如果递归的
被指定,它允许一个选择
子查询以按名称引用自身。这样的子查询必须具有以下形式
non_recursive_term UNION [ ALL | DISTINCT ] recursive_term
其中递归自引用必须出现在联盟
.每个查询只允许一个递归自引用。不支持递归数据修改语句,但您可以使用递归的结果选择
在数据修改语句中查询。看第 7.8 节例如。
的另一个效果递归的
就是它和
查询不需要排序:一个查询可以引用列表中后面的另一个查询。(但是,没有实现循环引用或相互递归。)没有递归的
,和
查询只能引用兄弟和
较早的查询和
列表。
当有多个查询时和
条款,递归的
应该只写一次,紧接着和
.它适用于和
子句,尽管它对不使用递归或前向引用的查询没有影响。
可选的搜索
子句计算一个搜索序列列可用于以广度优先或深度优先顺序对递归查询的结果进行排序。提供的列名列表指定用于跟踪已访问行的行键。一个名为的列*search_seq_col_name
*将被添加到结果列列表中和
询问。该列可以在外部查询中进行排序,以实现各自的排序。看第 7.8.2.1 节举些例子。
可选的循环
子句用于检测递归查询中的循环。提供的列名列表指定用于跟踪已访问行的行键。一个名为的列*cycle_mark_col_name
将被添加到结果列列表中和
询问。此列将设置为周期标记值
当检测到一个循环时,否则cycle_mark_default
.此外,当检测到循环时,递归联合的处理将停止。周期标记值
和cycle_mark_default
必须是常量,并且它们必须可强制转换为通用数据类型,并且该数据类型必须具有不等式运算符。(SQL 标准要求它们是布尔常量或字符串,但 PostgreSQL 不要求。)默认情况下,真的
和错误的
(类型布尔值
) 被使用。此外,有一列名为cycle_path_col_name
*将被添加到结果列列表中和
询问。此列在内部用于跟踪访问的行。看第 7.8.2.2 节举些例子。
这俩搜索
和循环
子句仅对递归有效和
查询。这*with_query
*必须是联盟
(要么联合所有
) 两个选择
(或等效的)命令(无嵌套联盟
s)。如果同时使用这两个子句,则由搜索
子句出现在由循环
条款。
主要查询和和
查询都是(名义上)同时执行的。这意味着数据修改语句的影响和
不能从查询的其他部分看到,除了阅读它的返回
输出。如果两个这样的数据修改语句尝试修改同一行,则结果未指定。
的一个关键属性和
查询是它们通常在每次执行主查询时只评估一次,即使主查询不止一次地引用它们。特别是,数据修改语句保证只执行一次,而不管主查询是读取它们的全部还是任何输出。
然而,一个和
可以标记查询未物化
取消此保证。在这种情况下,和
查询可以折叠到主查询中,就好像它是一个简单的子查询一样选择
在主查询中从
条款。如果主查询引用那个,这会导致重复计算和
多次查询;但如果每次这样的使用只需要几行和
查询的总输出,未物化
可以通过允许联合优化查询来提供净节省。未物化
如果它附加到一个和
递归或非无副作用的查询(即,不是普通的选择
不包含 volatile 函数)。
默认情况下,无副作用和
如果在主查询中仅使用一次,则查询将被折叠到主查询中从
条款。这允许在语义上不可见的情况下对两个查询级别进行联合优化。然而,这种折叠可以通过标记来防止和
查询为物化
.这可能很有用,例如,如果和
查询被用作优化围栏,以防止计划者选择错误的计划。v12 之前的 PostgreSQL 版本从未进行过这种折叠,因此为旧版本编写的查询可能依赖于和
充当优化围栏。
看第 7.8 节了解更多信息。
# 从
条款
这从
子句指定一个或多个源表选择
.如果指定了多个源,则结果是所有源的笛卡尔积(交叉连接)。但通常会添加资格条件(通过在哪里
) 将返回的行限制为笛卡尔积的一小部分。
这从
子句可以包含以下元素:
表名
现有表或视图的名称(可选模式限定)。如果只要
在表名之前指定,仅扫描该表。如果只要
如果未指定,则扫描该表及其所有后代表(如果有)。可选地,*
可以在表名之后指定以明确指示包含后代表。
别名
的替代名称从
包含别名的项目。别名用于简洁或消除自连接的歧义(同一个表被扫描多次)。当提供别名时,它会完全隐藏表或函数的实际名称;例如给出从 foo 作为 f
,其余的选择
必须参考这个从
项目为f
不是富
.如果编写了别名,则还可以编写列别名列表来为表的一个或多个列提供替代名称。
表样 *
采样方法* ( *
争论* [, ...] ) [ 可重复 ( *
种子* ) ]
一种表样
a 后的子句*表名
表示指定的采样方法
*should be used to retrieve a subset of the rows in that table. This sampling precedes the application of any other filters such asWHERE
clauses. The standard PostgreSQL distribution includes two sampling methods,BERNOULLI
andSYSTEM
, and other sampling methods can be installed in the database via extensions.
TheBERNOULLI
andSYSTEM
sampling methods each accept a single*argument
*which is the fraction of the table to sample, expressed as a percentage between 0 and 100. This argument can be anyreal
-valued expression. (Other sampling methods might accept more or different arguments.) These two methods each return a randomly-chosen sample of the table that will contain approximately the specified percentage of the table's rows. TheBERNOULLI
method scans the whole table and selects or ignores individual rows independently with the specified probability. TheSYSTEM
method does block-level sampling with each block having the specified chance of being selected; all rows in each selected block are returned. TheSYSTEM
method is significantly faster than theBERNOULLI
method when small sampling percentages are specified, but it may return a less-random sample of the table as a result of clustering effects.
The optionalREPEATABLE
clause specifies a*seed
number or expression to use for generating random numbers within the sampling method. The seed value can be any non-null floating-point value. Two queries that specify the same seed andargument
*如果同时没有更改表,则 values 将选择表的相同样本。但是不同的种子值通常会产生不同的样本。如果可重复
没有给出,则根据系统生成的种子为每个查询选择一个新的随机样本。请注意,某些附加采样方法不接受可重复
,并且每次使用都会产生新的样品。
选择
一个子选择
可以出现在从
条款。这就像它的输出是在这个单一的持续时间内被创建为一个临时表一样选择
命令。请注意,子选择
必须用括号括起来,还有一个别名必须为其提供。一种价值观
命令也可以在这里使用。
with_query_name
一种和
查询通过写入其名称来引用,就像查询的名称是表名一样。(事实上,和
query 出于主查询的目的隐藏任何同名的真实表。如有必要,您可以通过模式限定表名来引用同名的真实表。)可以以与表相同的方式提供别名。
函数名
函数调用可以出现在从
条款。(这对于返回结果集的函数特别有用,但可以使用任何函数。)这就像函数的输出在此单次执行期间被创建为临时表一样选择
命令。如果函数的结果类型是复合的(包括一个函数有多个出去
参数),每个属性成为隐式表中的单独列。
当可选具有顺序性
子句被添加到函数调用,类型的附加列大整数
将附加到函数的结果列。此列对函数结果集的行进行编号,从 1 开始。默认情况下,此列命名为序数.
可以以与表相同的方式提供别名。
如果编写了别名,则还可以编写列别名列表以提供函数复合返回类型的一个或多个属性的替代名称,包括序数列(如果存在)。多个函数调用可以合并为一个
从-条款项目通过包围他们
来自( ... ) 的行.
这样一个项目的输出是每个函数的第一行的连接,然后是每个函数的第二行,等等。如果某些函数产生的行比其他函数少,则用空值代替缺失的数据,这样返回的总行数始终与生成最多行的函数相同。
如果函数已被定义为返回记录
数据类型,然后是别名或关键字作为
必须存在,后跟表格中的列定义列表( *
列名* *
数据类型* [, ... ])
.列定义列表必须与函数返回的列的实际数量和类型相匹配。
使用时来自( ... ) 的行
语法,如果其中一个函数需要列定义列表,最好将列定义列表放在函数调用之后来自( ... ) 的行
.列定义列表可以放在来自( ... ) 的行
仅当只有一个函数且没有具有顺序性
条款。
使用序数
连同列定义列表,您必须使用来自( ... ) 的行
语法并将列定义列表放入其中来自( ... ) 的行
.
加入类型
之一
[ 内部联接
左[外]加入
右[外]加入
全[外]加入
交叉连接
为了
内
和外
连接类型,必须指定连接条件,即恰好其中之一自然
,在 *
加入条件*
, 要么使用 (*
加入列* [, ...])
.含义见下文。为了交叉连接
, 这些子句都不能出现。一种
加入
子句结合了两个从
项目,为方便起见,我们将其称为“表格”,但实际上它们可以是任何类型的从
物品。必要时使用括号来确定嵌套顺序。在没有括号的情况下,加入
s 从左到右嵌套。在任何情况下加入
比逗号分隔得更紧密从
- 列出项目。
交叉连接
和内部联接
产生一个简单的笛卡尔积,与在顶层列出两个表得到的结果相同从
,但受连接条件(如果有)的限制。交叉连接
相当于内连接开启(真)
,也就是说,没有任何行被限定删除。这些连接类型只是一种符号上的便利,因为它们什么都不做,你不能用普通的从
和在哪里
.
左外连接
返回合格笛卡尔积中的所有行(即所有通过其连接条件的组合行),加上左侧表中没有通过连接条件的右侧行的每一行的副本。通过为右侧列插入空值,此左侧行扩展到连接表的整个宽度。请注意,只有加入
在决定哪些行匹配时会考虑子句自身的条件。之后应用外部条件。
反过来,右外连接
返回所有连接的行,加上每个不匹配的右侧行(左侧以空值扩展)的一行。这只是一种符号方便,因为您可以将其转换为左外连接
通过切换左右表。
全外连接
返回所有连接的行,加上每个不匹配的左侧行(右侧以空值扩展)的一行,以及每个不匹配的右侧行(左侧以空值扩展)的一行。
在 *
加入条件*
*加入条件
*是导致类型值的表达式布尔值
(类似于一个在哪里
子句),它指定连接中的哪些行被认为是匹配的。
使用 ( *
加入列* [, ...] ) [ 作为 *
加入使用别名* ]
形式子句使用(a,b,...)
是简写ON left_table.a = right_table.a AND left_table.b = right_table.b ...
.还,使用
意味着每对等效列中只有一个将包含在连接输出中,而不是两者都包含。
如果一个*加入使用别名
指定名称时,它为连接列提供表别名。只有列中列出的连接列使用
子句可通过此名称寻址。不同于一般的别名
,这不会从查询的其余部分隐藏连接表的名称。也不同于常规别名
*,您不能编写列别名列表 - 连接列的输出名称与它们在使用
列表。
自然的
自然的
是 a 的简写使用
列出两个表中具有匹配名称的所有列。如果没有通用的列名,自然的
相当于正确
.
侧
这侧
关键字可以在子之前选择
从
物品。这允许子选择
引用列从
出现在它前面的项目从
列表。(没有侧
, 每个子选择
独立评估,因此不能交叉引用任何其他从
物品。)
侧
也可以在函数调用之前从
item,但在这种情况下它是一个干扰词,因为函数表达式可以参考前面从
在任何情况下的项目。
一种侧
项目可以出现在顶层从
列表,或在一个加入
树。在后一种情况下,它也可以指代左侧的任何项目加入
它位于右侧。
当一个从
项目包含侧
交叉引用,评估过程如下:对于每一行从
提供交叉引用的列或一组多行的项目从
提供列的项目,侧
使用该行或行集的列值评估项目。结果行像往常一样与计算它们的行连接。对列源表中的每一行或每组行重复此操作。
列源表必须是内
或者剩下
加入了侧
项,否则将没有明确定义的行集来计算侧
物品。因此,虽然一个结构如*
X* 右连接横向 *
是*
在语法上是有效的,实际上是不允许的*是
参考X
*.
# 在哪里
条款
可选的在哪里
子句具有一般形式
WHERE condition
在哪里*(健康)状况
*是任何计算结果类型的表达式布尔值
.任何不满足此条件的行都将从输出中删除。如果在实际行值替换任何变量引用时返回 true,则该行满足条件。
# 通过...分组
条款
可选的通过...分组
子句具有一般形式
GROUP BY [ ALL | DISTINCT ] grouping_element [, ...]
通过...分组
将所有选定的行压缩为一行,这些行对分组表达式共享相同的值。一个*表达
在 a 内使用分组元素
*可以是输入列名称,也可以是输出列的名称或序号 (选择
列表项),或由输入列值形成的任意表达式。如有歧义,通过...分组
name 将被解释为输入列名而不是输出列名。
如果有任何一个分组集
,卷起
或者立方体
作为分组元素存在,则通过...分组
子句作为一个整体定义了一些独立的*分组集
.这样的效果相当于构造一个联合所有
在以单个分组集为它们的子查询之间通过...分组
条款。可选的清楚的
子句在处理之前删除重复集;它确实不是*改造联合所有
成一个工会区别
.有关分组集处理的更多详细信息,请参见第 7.2.4 节.
如果使用了聚合函数,则在构成每个组的所有行中计算,为每个组生成一个单独的值。(如果有聚合函数但没有通过...分组
子句,查询被视为具有包含所有选定行的单个组。)可以通过附加一个来进一步过滤提供给每个聚合函数的行集筛选
聚合函数调用的子句;看第 4.2.7 节了解更多信息。当一个筛选
子句存在时,只有与它匹配的那些行才会包含在该聚合函数的输入中。
什么时候通过...分组
存在,或存在任何聚合函数,它对选择
列出表达式以引用未分组的列,除非在聚合函数中或当未分组的列在功能上依赖于分组的列时,因为否则将为未分组的列返回多个可能的值。如果分组列(或其子集)是包含未分组列的表的主键,则存在功能依赖性。
请记住,所有聚合函数都在评估任何“标量”表达式之前进行评估拥有
条款或选择
列表。这意味着,例如,一个案子
表达式不能用于跳过聚合函数的评估;看第 4.2.14 节.
目前,无密钥更新
,更新
,分享
和关键分享
不能指定通过...分组
.
# 拥有
条款
可选的拥有
子句具有一般形式
HAVING condition
在哪里*(健康)状况
*与指定的相同在哪里
条款。
拥有
消除不满足条件的组行。拥有
不同于在哪里
:在哪里
在应用之前过滤单个行通过...分组
, 尽管拥有
过滤器组创建的行通过...分组
.中引用的每一列*(健康)状况
*必须明确引用分组列,除非引用出现在聚合函数中或未分组列在功能上依赖于分组列。
的存在拥有
将查询变成分组查询,即使没有通过...分组
条款。这与查询包含聚合函数但不包含聚合函数时发生的情况相同通过...分组
条款。所有选定的行都被视为一个组,并且选择
列出和拥有
子句只能从聚合函数中引用表列。如果拥有
条件为真,如果不为真则零行。
目前,无密钥更新
,更新
,分享
和关键分享
不能指定拥有
.
# 窗户
条款
可选的窗户
子句具有一般形式
WINDOW window_name AS ( window_definition ) [, ...]
在哪里*窗口名称
是一个可以引用的名称超过
子句或后续窗口定义,以及窗口定义
*是
[ existing_window_name ]
[ PARTITION BY expression [, ...] ]
[ ORDER BY expression [ ASC | DESC | USING operator ] [ NULLS { FIRST | LAST } ] [, ...] ]
[ frame_clause ]
如果*现有窗口名称
*被指定它必须引用一个较早的条目窗户
列表;新窗口从该条目复制其分区子句,以及其排序子句(如果有)。在这种情况下,新窗口不能指定自己的分区方式
子句,它可以指定订购方式
仅当复制的窗口没有时。新窗口总是使用自己的框架子句;复制的窗口不得指定框架子句。
的元素分区方式
list 的解释方式与 a 的元素大致相同通过...分组
子句,除了它们总是简单的表达式,而不是输出列的名称或编号。另一个区别是这些表达式可以包含聚合函数调用,这在常规中是不允许的通过...分组
条款。它们在这里是允许的,因为在分组和聚合之后发生窗口化。
同样,元素订购方式
列表的解释方式与语句级别的元素大致相同订购方式
子句,但表达式始终被视为简单表达式,而不是输出列的名称或编号。
可选的*框架子句
定义了窗框对于依赖于框架的窗口函数(并非全部)。窗口框架是查询的每一行的一组相关行(称为当前行*)。这*框架子句
*可以是其中之一
{ RANGE | ROWS | GROUPS } frame_start [ frame_exclusion ]
{ RANGE | ROWS | GROUPS } BETWEEN frame_start AND frame_end [ frame_exclusion ]
在哪里*frame_start
和帧结束
*可以是其中之一
UNBOUNDED PRECEDING
offset PRECEDING
CURRENT ROW
offset FOLLOWING
UNBOUNDED FOLLOWING
和*框架排除
*可以是其中之一
EXCLUDE CURRENT ROW
EXCLUDE GROUP
EXCLUDE TIES
EXCLUDE NO OTHERS
如果*帧结束
被省略,默认为当前行
.限制是frame_start
不可能是无界跟随
,帧结束
不可能是前无界
, 和帧结束
选择不能出现在上面的列表中frame_start
和帧结束
选项比frame_start
*选择确实——例如当前行和 * 之间的范围
抵消* 前文
不允许。
默认框架选项是范围无界前
, 这与无界前行和当前行之间的范围
;它将框架设置为从分区开始到当前行的最后一行的所有行同行(窗口的一行订购方式
子句认为等同于当前行;如果没有,所有行都是对等的订购方式
)。一般来说,前无界
表示帧从分区的第一行开始,类似地无界跟随
表示帧以分区的最后一行结束,无论范围
,行
或者组
模式。在行
模式,当前行
表示帧以当前行开始或结束;但在范围
或者组
mode 表示帧以当前行的第一个或最后一个节点开始或结束订购方式
订购。这*抵消
* 前
和*抵消
* 下列的
选项的含义因帧模式而异。在行
模式*抵消
是一个整数,指示帧在当前行之前或之后开始或结束那么多行。在组
模式抵消
是一个整数,指示帧在当前行的对等组之前或之后开始或结束那么多对等组,其中对等组是一组根据窗口等效的行订购方式
条款。在范围
模式,使用一个抵消
选项要求恰好有一个订购方式
窗口定义中的列。然后框架包含那些排序列值不超过的行抵消
小于(对于前
) 或多于 (对于下列的
) 当前行的排序列值。在这些情况下,数据类型抵消
表达式取决于排序列的数据类型。对于数字排序列,它通常与排序列的类型相同,但对于日期时间排序列,它是间隔
.在所有这些情况下,价值抵消
必须为非空且非负数。此外,虽然抵消
*不必是简单的常量,也不能包含变量、聚合函数或窗口函数。
这*框架排除
*选项允许从框架中排除当前行周围的行,即使根据框架开始和框架结束选项将它们包括在内。排除当前行
从框架中排除当前行。排除组
从框架中排除当前行及其排序对等方。排除关系
从框架中排除当前行的任何对等方,但不排除当前行本身。不排除其他人
简单地明确指定不排除当前行或其对等点的默认行为。
请注意,行
模式可以产生不可预知的结果,如果订购方式
ordering 不会唯一地对行进行排序。这范围
和组
模式旨在确保在订购方式
排序被同等对待:给定对等组的所有行都将在框架中或从框架中排除。
一个目的窗户
子句是指定的行为窗口函数出现在查询的选择
列表或者订购方式
条款。这些函数可以参考窗户
子句条目中的名称超过
条款。一种窗户
但是,子句条目不必在任何地方引用;如果它没有在查询中使用,它会被忽略。可以不使用任何窗口函数窗户
子句,因为窗口函数调用可以直接在它的超过
条款。然而窗户
当多个窗口函数需要相同的窗口定义时,子句可以节省输入。
目前,无密钥更新
,更新
,分享
和关键分享
不能指定窗户
.
窗口函数在详细描述第 3.5 节,第 4.2.8 节, 和第 7.2.5 节.
# 选择
列表
这选择
列表(在关键词之间选择
和从
) 指定形成输出行的表达式选择
陈述。表达式可以(并且通常会)引用在从
条款。
就像在表中一样,a 的每个输出列选择
有一个名字。在一个简单的选择
此名称仅用于标记要显示的列,但当选择
是较大查询的子查询,该名称被较大查询视为子查询产生的虚拟表的列名。要指定用于输出列的名称,请编写作为
*输出名称
*在列的表达式之后。(可以省略作为
,但前提是所需的输出名称不匹配任何 PostgreSQL 关键字(请参阅附录 C)。为了防止将来可能添加关键字,建议您始终编写作为
或双引号输出名称。)如果您不指定列名,则 PostgreSQL 会自动选择一个名称。如果列的表达式是一个简单的列引用,则选择的名称与该列的名称相同。在更复杂的情况下,可以使用函数或类型名称,或者系统可能会使用生成的名称,例如?柱子?
.
输出列的名称可用于引用该列的值订购方式
和通过...分组
条款,但不在在哪里
要么拥有
条款;在那里你必须写出表达式。
而不是一个表情,*
可以写在输出列表中作为所选行的所有列的简写。另外,你可以写*
表名*.*
作为仅来自该表的列的简写。在这些情况下,无法指定新名称作为
;输出列名将与表列名相同。
根据 SQL 标准,输出列表中的表达式应在应用前计算清楚的
,订购方式
, 或者限制
.这在使用时显然是必要的清楚的
,因为否则不清楚哪些值是不同的。然而,在许多情况下,如果输出表达式在订购方式
和限制
;特别是如果输出列表包含任何易失或昂贵的功能。通过这种行为,函数评估的顺序更加直观,并且不会有与从未出现在输出中的行相对应的评估。PostgreSQL 将在排序和限制后有效地评估输出表达式,只要这些表达式没有被引用清楚的
,订购方式
或者通过...分组
.(作为反例,从选项卡 ORDER BY 1 中选择 f(x)
显然必须评估f(x)
排序之前。)包含返回集合函数的输出表达式在排序之后和限制之前有效地评估,因此限制
将采取行动切断来自集合返回功能的输出。
# 笔记
PostgreSQL 9.6 之前的版本没有提供任何关于输出表达式求值时间与排序和限制的保证;它取决于所选查询计划的形式。
# 清楚的
条款
如果选择不同的
指定时,从结果集中删除所有重复行(从每组重复项中保留一行)。全选
指定相反:保留所有行;这是默认设置。
选择不同(*
表达* [, ...] )
仅保留给定表达式计算结果等于的每组行的第一行。这区别开
表达式使用与 for 相同的规则进行解释订购方式
(往上看)。请注意,每组的“第一行”是不可预测的,除非订购方式
用于确保所需的行首先出现。例如:
SELECT DISTINCT ON (location) location, time, report
FROM weather_reports
ORDER BY location, time DESC;
检索每个位置的最新天气报告。但是如果我们没有使用订购方式
为了强制每个位置的时间值降序排列,我们会从每个位置的不可预测时间得到一份报告。
这区别开
表达式必须匹配最左边的订购方式
表达式。这订购方式
子句通常包含额外的表达式,这些表达式确定每个行中所需的优先级区别开
团体。
目前,无密钥更新
,更新
,分享
和关键分享
不能指定清楚的
.
# 联盟
条款
这联盟
子句具有以下一般形式:
select_statement UNION [ ALL | DISTINCT ] select_statement
*选择语句
*是任何选择
没有声明的订购方式
,限制
,无密钥更新
,更新
,分享
, 或者关键分享
条款。(订购方式
和限制
如果它被括在括号中,则可以附加到子表达式。如果没有括号,这些条款将被视为适用于联盟
,而不是它的右手输入表达式。)
这联盟
运算符计算所涉及的返回行的集合并集选择
陈述。如果一行出现在至少一个结果集中,则它位于两个结果集的集合并集中。他们俩选择
表示直接操作数的语句联盟
必须产生相同数量的列,并且对应的列必须是兼容的数据类型。
的结果联盟
不包含任何重复的行,除非全部
选项被指定。全部
防止消除重复。(所以,联合所有
通常明显快于联盟
;采用全部
什么时候可以。)清楚的
可以写入显式指定消除重复行的默认行为。
多种的联盟
同一运营商选择
语句从左到右求值,除非括号中另有说明。
现在,无密钥更新
, 更新
, 分享
和关键分享
不能为 a 指定联盟
结果或任何输入联盟
.
# 相交
条款
这相交
子句具有以下一般形式:
select_statement INTERSECT [ ALL | DISTINCT ] select_statement
*选择语句
*是任何选择
没有声明的订购方式
, 限制
, 无密钥更新
, 更新
,分享
, 或者关键分享
条款。
这相交
运算符计算所涉及的返回的行的集合交集选择
陈述。如果一行出现在两个结果集中,则它位于两个结果集中的交集。
的结果相交
不包含任何重复的行,除非全部
选项被指定。和全部
, 一行有*米
左表中的重复项和n
右表中的重复项将出现 min(米
,n
*) 结果集中的次数。清楚的
可以写入显式指定消除重复行的默认行为。
多相交
同一运营商选择
语句从左到右进行评估,除非括号另有说明。相交
比绑得更紧联盟
.那是,A 联合 B 相交 C
将被读作A UNION (B INTERSECT C)
.
目前,无密钥更新
,更新
,分享
和关键分享
不能为相交
结果或任何输入相交
.
# 除了
条款
这除了
子句具有以下一般形式:
select_statement EXCEPT [ ALL | DISTINCT ] select_statement
*选择语句
*是任何选择
没有声明的订购方式
,限制
,无密钥更新
,更新
,分享
, 要么关键分享
条款。
这除了
运算符计算左侧结果中的行集选择
声明,但不在正确的结果中。
的结果除了
不包含任何重复的行,除非全部
选项被指定。和全部
, 一行有*米
左表中的重复项和n
右表中的重复项将出现 max(米
-n
*,0) 次在结果集中。清楚的
可以写入显式指定消除重复行的默认行为。
多种的除了
同一运营商选择
语句从左到右进行评估,除非括号另有说明。除了
绑定在同一级别联盟
.
现在,无密钥更新
, 更新
, 分享
和关键分享
不能为除了
结果或任何输入除了
.
# 订购方式
条款
可选的订购方式
子句具有以下一般形式:
ORDER BY expression [ ASC | DESC | USING operator ] [ NULLS { FIRST | LAST } ] [, ...]
这订购方式
子句使结果行根据指定的表达式进行排序。如果根据最左边的表达式,两行相等,则根据下一个表达式进行比较,依此类推。如果根据所有指定的表达式它们相等,则它们以与实现相关的顺序返回。
每个*表达
*可以是输出列的名称或序号 (选择
列表项),或者它可以是由输入列值形成的任意表达式。
序数是指输出列的序数(从左到右)位置。此功能可以根据没有唯一名称的列定义排序。这从来都不是绝对必要的,因为总是可以使用作为
条款。
也可以使用任意表达式订购方式
子句,包括未出现在选择
输出列表。因此,以下陈述是有效的:
SELECT name FROM distributors ORDER BY code;
此功能的一个限制是,订购方式
适用于 a 结果的子句联盟
,相交
, 或者除了
子句只能指定输出列名或编号,不能指定表达式。
如果订购方式
表达式是一个简单的名称,它同时匹配输出列名和输入列名,订购方式
将其解释为输出列名。这与选择的相反通过...分组
会在同样的情况下。这种不一致性是为了与 SQL 标准兼容。
可以选择添加关键字ASC
(上升)或DESC
(降序)在任何表达式之后订购方式
条款。如果没有指定,ASC
默认情况下假定。或者,可以在使用
条款。排序运算符必须是某个 B 树运算符族的小于或大于成员。ASC
通常相当于使用 <
和DESC
通常相当于使用 >
.(但用户定义数据类型的创建者可以准确定义默认排序顺序是什么,并且它可能对应于具有其他名称的运算符。)
如果NULLS LAST
指定时,空值排在所有非空值之后;如果NULLS FIRST
指定时,空值排在所有非空值之前。如果两者都没有指定,则默认行为是NULLS LAST
什么时候ASC
是指定的或暗示的,并且NULLS FIRST
什么时候DESC
是指定的(因此,默认情况下就像空值大于非空值一样)。什么时候使用
指定时,默认空值排序取决于运算符是小于还是大于运算符。
请注意,排序选项仅适用于它们遵循的表达式;例如按 x, y DESC 排序
与按 x DESC、y DESC 排序
.
字符串数据根据应用于被排序的列的排序规则进行排序。可以在需要时通过包含整理
条款中的*表达
*, 例如ORDER BY mycolumn COLLATE "en_US"
.有关更多信息,请参阅第 4.2.10 节和第 24.2 节.
# 限制
条款
这限制
clause consists of two independent sub-clauses:
LIMIT { count | ALL }
OFFSET start
The parameter*count
specifies the maximum number of rows to return, whilestart
specifies the number of rows to skip before starting to return rows. When both are specified,start
rows are skipped before starting to count thecount
*rows to be returned.
If the*count
expression evaluates to NULL, it is treated asLIMIT ALL
, i.e., no limit. Ifstart
*evaluates to NULL, it is treated the same asOFFSET 0
.
SQL:2008 introduced a different syntax to achieve the same result, which PostgreSQL also supports. It is:
OFFSET start { ROW | ROWS }
FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } { ONLY | WITH TIES }
In this syntax, the*start
orcount
value is required by the standard to be a literal constant, a parameter, or a variable name; as a PostgreSQL extension, other expressions are allowed, but will generally need to be enclosed in parentheses to avoid ambiguity. Ifcount
*is omitted in aFETCH
clause, it defaults to 1. TheWITH TIES
选项用于根据订购方式
条款;订购方式
在这种情况下是强制性的,并且跳过锁定
不允许。排
和行
也第一的
和下一个
是不影响这些条款效果的干扰词。根据标准,抵消
子句必须在拿来
条款,如果两者都存在;但 PostgreSQL 比较宽松,允许任何一种顺序。
使用时限制
, 使用订购方式
将结果行约束为唯一顺序的子句。否则,您将获得查询行的不可预测的子集——您可能会要求第 10 到第 20 行,但第 10 到第 20 行的顺序是什么?除非您指定,否则您不知道什么顺序订购方式
.
查询规划器采用限制
在生成查询计划时考虑,因此您很可能会根据您的用途获得不同的计划(产生不同的行顺序)限制
和抵消
.因此,使用不同的限制
/抵消
选择查询结果的不同子集的值会给出不一致的结果除非您强制执行可预测的结果排序订购方式
.这不是错误;这是 SQL 不承诺以任何特定顺序提供查询结果这一事实的固有结果,除非订购方式
用于约束顺序。
甚至可以重复执行相同的限制
查询返回表行的不同子集,如果没有订购方式
强制选择确定性子集。同样,这不是错误。在这种情况下,根本无法保证结果的确定性。
# 锁定条款
更新
,无密钥更新
,分享
和关键分享
是锁定条款;它们影响如何选择
锁定从表中获取的行。
锁定子句具有一般形式
FOR lock_strength [ OF table_name [, ...] ] [ NOWAIT | SKIP LOCKED ]
在哪里*lock_strength
*可以是其中之一
UPDATE
NO KEY UPDATE
SHARE
KEY SHARE
有关每种行级锁定模式的详细信息,请参阅第 13.3.2 节.
要防止操作等待其他事务提交,请使用现在等待
或者跳过锁定
选项。和现在等待
,如果不能立即锁定选定的行,该语句将报告错误,而不是等待。和跳过锁定
,任何无法立即锁定的选定行都将被跳过。跳过锁定的行会提供不一致的数据视图,因此这不适用于通用工作,但可用于避免多个消费者访问类似队列的表时发生锁争用。注意现在等待
和跳过锁定
仅适用于行级锁 — 必需行共享
表级锁仍然以普通方式获取(参见第 13 章)。您可以使用锁
与现在等待
第一个选项,如果您需要在不等待的情况下获取表级锁。
如果在锁定子句中命名了特定表,则只有来自这些表的行被锁定;中使用的任何其他表格选择
像往常一样简单地阅读。没有表列表的锁定子句会影响语句中使用的所有表。如果锁定子句应用于视图或子查询,它会影响视图或子查询中使用的所有表。但是,这些条款不适用于和
主查询引用的查询。如果您希望行锁定发生在一个和
查询,在和
询问。
如果需要为不同的表指定不同的锁定行为,可以编写多个锁定子句。如果同一个表被多个锁定子句提及(或隐式影响),则将其处理为好像它仅由最强的一个指定。类似地,一个表被处理为现在等待
如果在影响它的任何条款中规定了这一点。否则,它被处理为跳过锁定
如果在影响它的任何条款中规定了这一点。
锁定子句不能用于返回的行不能与单个表行明确标识的上下文中;例如,它们不能与聚合一起使用。
当锁定子句出现在选择
查询,锁定的行正是查询返回的行;在连接查询的情况下,锁定的行是那些有助于返回连接行的行。此外,在查询快照时满足查询条件的行将被锁定,但如果在快照后更新且不再满足查询条件,则不会返回。如果一个限制
使用时,一旦返回足够多的行以满足限制,锁定就会停止(但请注意,跳过的行抵消
将被锁定)。同样,如果在游标的查询中使用了锁定子句,则只有游标实际获取或跳过的行才会被锁定。
当锁定子句出现在子选择
,锁定的行是子查询返回给外部查询的行。这可能涉及比单独检查子查询所建议的更少的行,因为来自外部查询的条件可能用于优化子查询的执行。例如,
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;
将无法保存更新
锁定后回滚到
.这已在 9.3 版中修复。
# 警告
这是可能的选择
命令运行在阅读已提交
事务隔离级别和使用订购方式
和一个锁定子句以乱序返回行。这是因为订购方式
首先应用。该命令对结果进行排序,但随后可能会阻止尝试获取一个或多个行的锁定。一旦选择
解除阻塞时,某些排序列值可能已被修改,导致这些行看起来是乱序的(尽管它们在原始列值方面是按顺序排列的)。这可以在需要时通过放置更新/分享
子查询中的子句,例如
SELECT * FROM (SELECT * FROM mytable FOR UPDATE) ss ORDER BY column1;
请注意,这将导致锁定所有行我的表
, 然而更新
在顶层只会锁定实际返回的行。这可能会产生显着的性能差异,特别是如果订购方式
与限制
或其他限制。因此,仅当预期排序列的并发更新并且需要严格排序的结果时,才建议使用此技术。
在可重复阅读
要么可序列化
事务隔离级别,这将导致序列化失败(带有SQLSTATE
的'40001'
),因此在这些隔离级别下不可能接收到乱序的行。
# 桌子
命令
命令
TABLE name
相当于
SELECT * FROM name
它可以用作顶级命令或在复杂查询的部分中用作节省空间的语法变体。只有和
,联盟
,相交
,除了
,订购方式
,限制
,抵消
,拿来
和为了
锁定子句可以与桌子
;这在哪里
子句和任何形式的聚合都不能使用。
# 例子
加入表电影
与桌子经销商
:
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
## Compatibility
Of course, the `SELECT` statement is compatible with the SQL standard. But there are some extensions and some missing features.
### Omitted `FROM` Clauses
PostgreSQL allows one to omit the `FROM` clause. It has a straightforward use to compute the results of simple expressions:
选择 2+2;
?柱子?
# 空的选择
列表
之后的输出表达式列表选择
可以为空,生成一个零列的结果表。根据 SQL 标准,这不是有效的语法。PostgreSQL 允许它与允许零列表保持一致。但是,当清楚的
用来。
# 省略作为
关键词
在 SQL 标准中,可选关键字作为
只要新列名是有效的列名(即,与任何保留关键字不同),就可以在输出列名之前省略。PostgreSQL 的限制稍微多一些:作为
如果新的列名完全匹配任何关键字,无论是否保留,都是必需的。推荐的做法是使用作为
或双引号输出列名,以防止与将来添加的关键字发生任何可能的冲突。
在从
项目,标准和 PostgreSQL 都允许作为
在作为非保留关键字的别名之前被省略。但这对于输出列名是不切实际的,因为语法不明确。
# 只要
和继承
SQL 标准在编写时要求在表名周围加上括号只要
, 例如SELECT * FROM ONLY (tab1), ONLY (tab2) WHERE ...
.PostgreSQL 认为这些括号是可选的。
PostgreSQL 允许尾随*
被写入明确指定非只要
包括子表的行为。标准不允许这样做。
(这些点同样适用于所有支持只要
选项。)
# 表样
条款限制
这表样
子句目前仅在常规表和物化视图上被接受。根据 SQL 标准,应该可以将其应用于任何从
物品。
# 函数调用从
PostgreSQL 允许将函数调用直接编写为从
列表。在 SQL 标准中,有必要将这样的函数调用包装在一个子类中。选择
;也就是说,语法从 *
功能*(...) *
别名*
大约相当于从横向(选择 *
功能*(...)) *
别名*
.注意侧
被认为是隐含的;这是因为标准要求侧
语义未嵌套()
项目在从
.PostgreSQL 对待未嵌套()
与其他集合返回函数相同。
# 可用的命名空间通过...分组
和订购方式
在 SQL-92 标准中,一个订购方式
子句只能使用输出列名或数字,而通过...分组
子句只能使用基于输入列名的表达式。PostgreSQL 扩展了这些子句中的每一个以允许其他选择(但如果存在歧义,它会使用标准的解释)。PostgreSQL 还允许两个子句指定任意表达式。请注意,出现在表达式中的名称将始终被视为输入列名称,而不是输出列名称。
SQL:1999 和更高版本使用稍微不同的定义,它不完全向上兼容 SQL-92.然而,在大多数情况下,PostgreSQL 会解释一个订购方式
或者通过...分组
表达方式与 SQL:1999 相同。
# 功能依赖
PostgreSQL 识别函数依赖(允许从通过...分组
) 仅当表的主键包含在通过...分组
列表。SQL 标准指定了应识别的附加条件。
# 限制
和抵消
条款限制
和抵消
是特定于 PostgreSQL 的语法,也被 MySQL 使用。SQL:2008 标准引入了子句偏移量 ... FETCH {FIRST|NEXT} ...
对于相同的功能,如上图所示限制条款.IBM DB2 也使用此语法。(为 Oracle 编写的应用程序经常使用涉及自动生成的行数
列,在 PostgreSQL 中不可用,以实现这些子句的效果。)
# 无密钥更新
,更新
,分享
,关键分享
虽然更新
出现在 SQL 标准中,标准只允许它作为一个选项声明光标
.PostgreSQL 允许它在任何选择
查询以及在子选择
s,但这是一个扩展。这无密钥更新
,分享
和关键分享
变体,以及现在等待
和跳过锁定
选项,不出现在标准中。
# 中的数据修改语句和
PostgreSQL 允许插入
,更新
, 和删除
用作和
查询。这在 SQL 标准中找不到。
# 非标准条款
区别开 ( ... )
是 SQL 标准的扩展。
来自( ... ) 的行
是 SQL 标准的扩展。
这物化
和未物化
的选项和
是 SQL 标准的扩展。