天天看點

第二章 SQL指令參考-SELECT

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