# 7.2\. 表表達式
_表表達式_計算一個表,它包含一個`FROM`子句, 該子句可以根據需要選用`WHERE`, `GROUP BY`,`HAVING` 子句。大部分表表達式只是指向磁盤上的一個所謂的基本表, 但是我們可以用更復雜的表達式以各種方法修改或組合基本表。
表表達式里的`WHERE`, `GROUP BY`, `HAVING` 子句聲明一系列對源自`FROM`子句的表的轉換操作。 所有這些轉換最后生成一個虛擬表,傳遞給選擇列表計算輸出行。
## 7.2.1\. `FROM` 子句
[_FROM_ 子句](#calibre_link-516) 從一個逗號分隔的表引用列表中生成一個虛擬表。
```
FROM _table_reference_ [, `_table_reference_` [, ...]]
```
表引用可以是一個表名字(可能有模式修飾)或者是一個生成的表, 比如子查詢、表連接、或這些東西的復雜組合。如果在`FROM`子句中列出了多于一個表, 那么它們交叉連接(見下文)形成一個派生表,該表可以進行`WHERE`, `GROUP BY`, `HAVING`子句的轉換處理,并最后生成表表達式的結果。
如果一個表引用是一個簡單的父表的名字,那么將包括其所有后代子表的行, 除非你在該表名字前面加`ONLY`關鍵字(這樣任何子表都會被忽略)。
除了在表名字前面加`ONLY`,你可以在表名字后面寫`*` 明確指定包括后代表。寫`*`不是必須的,因為這個行為是默認的 (除非你已經改變了[sql_inheritance](#calibre_link-2218)配置選項里面的設置)。 然而寫`*`可能對于強調搜索額外的表是有用的。
### 7.2.1.1\. 連接表
一個連接表是根據特定的連接規則從兩個其它表(真實表或生成表)中派生的表。 我們支持內連接、外連接、交叉連接。
**連接類型**
交叉連接
```
_T1_ CROSS JOIN _T2_
```
對每個來自`_T1_`和`_T2_` 的行進行組合(也就是,一個笛卡爾積),連接成的表將包含這樣的行: 所有`_T1_`里面的字段后面跟著所有`_T2_` 里面的字段。如果兩表分別有 N 和 M 行,連接成的表將有 N*M 行。
`FROM` `_T1_` CROSS JOIN `_T2_` 等效于`FROM` `_T1_`,`_T2_`。 它還等效于`FROM` `_T1_` INNER JOIN `_T2_` ON TRUE(見下文)。
條件連接
```
_T1_ { [INNER] | { LEFT | RIGHT | FULL } [OUTER] } JOIN _T2_ ON _boolean_expression_
_T1_ { [INNER] | { LEFT | RIGHT | FULL } [OUTER] } JOIN _T2_ USING ( _join column list_ )
_T1_ NATURAL { [INNER] | { LEFT | RIGHT | FULL } [OUTER] } JOIN _T2_
```
`INNER`和`OUTER`對所有連接類型都是可選的。 `INNER`為缺省。`LEFT`, `RIGHT`, 和`FULL`隱含外連接。
_連接條件_在`ON`或`USING`子句里聲明, 或者用關鍵字`NATURAL`隱含地聲明。 連接條件判斷來自兩個源表中的那些行是"匹配"的,這些我們將在下面詳細解釋。
`ON`子句是最常見的連接條件的類型:它接收一個和`WHERE` 子句相同的布爾表達式。如果兩個分別來自`_T1_`和`_T2_` 的行在`ON`表達式上運算的結果為真,那么它們就算是匹配的行。
`USING`是一個連接條件的縮寫語法:它接收一個用逗號分隔的字段名列表, 這些字段必須是連接表共有的并且其值必須相同。最后,`JOIN USING` 會將每一對相等的輸入字段輸出為一個字段,其后跟著所有其它字段。 因此,`USING (a, b, c)` 等效于`ON (t1.a = t2.a AND t1.b = t2.b AND t1.c = t2.c)` 只不過是如果使用了`ON`,那么在結果里`a`, `b`和`c` 字段都會有兩個,而用`USING`的時候就只會有一個(如果使用了`SELECT *` 的話,他們會優先發生)。
最后,`NATURAL`是`USING`的縮寫形式: 它自動形成一個由兩個表中同名的字段組成的`USING`列表(同名字段只出現一次)。 如果沒有同名的字段,`NATURAL`的行為會像`CROSS JOIN`。
條件連接可能的類型是:
`INNER JOIN`
內連接。對于 T1 中的每一行 R1 ,如果能在 T2 中找到一個或多個滿足連接條件的行, 那么這些滿足條件的每一行都在連接表中生成一行。
`LEFT OUTER JOIN`
左外連接。首先執行一次內連接。然后為每一個 T1 中無法在 T2 中找到匹配的行生成一行, 該行中對應 T2 的列用 NULL 補齊。因此,生成的連接表里總是包含來自 T1 里的每一行至少一個副本。
`RIGHT OUTER JOIN`
右外連接。首先執行一次內連接。然后為每一個 T2 中無法在 T1 中找到匹配的行生成一行, 該行中對應 T1 的列用 NULL 補齊。因此,生成的連接表里總是包含來自 T2 里的每一行至少一個副本。
`FULL OUTER JOIN`
全連接。首先執行一次內連接。然后為每一個 T1 與 T2 中找不到匹配的行生成一行, 該行中無法匹配的列用 NULL 補齊。因此,生成的連接表里無條件地包含 T1 和 T2 里的每一行至少一個副本。
如果`_T1_`和`_T2_` 之一或全部是可以連接的表,那么所有類型的連接都可以串連或嵌套在一起。 你可以在`JOIN`子句周圍使用圓括弧來控制連接順序,如果沒有圓括弧, 那么`JOIN`子句從左向右嵌套。
為了解釋這些問題,假設我們有一個表`t1`:
```
num | name
-----+------
1 | a
2 | b
3 | c
```
和`t2`:
```
num | value
-----+-------
1 | xxx
3 | yyy
5 | zzz
```
然后我們用不同的連接方式可以獲得各種結果:
```
<samp class="literal">=></samp> <kbd class="literal">SELECT * FROM t1 CROSS JOIN t2;</kbd>
num | name | num | value
-----+------+-----+-------
1 | a | 1 | xxx
1 | a | 3 | yyy
1 | a | 5 | zzz
2 | b | 1 | xxx
2 | b | 3 | yyy
2 | b | 5 | zzz
3 | c | 1 | xxx
3 | c | 3 | yyy
3 | c | 5 | zzz
(9 rows)
<samp class="literal">=></samp> <kbd class="literal">SELECT * FROM t1 INNER JOIN t2 ON t1.num = t2.num;</kbd>
num | name | num | value
-----+------+-----+-------
1 | a | 1 | xxx
3 | c | 3 | yyy
(2 rows)
<samp class="literal">=></samp> <kbd class="literal">SELECT * FROM t1 INNER JOIN t2 USING (num);</kbd>
num | name | value
-----+------+-------
1 | a | xxx
3 | c | yyy
(2 rows)
<samp class="literal">=></samp> <kbd class="literal">SELECT * FROM t1 NATURAL INNER JOIN t2;</kbd>
num | name | value
-----+------+-------
1 | a | xxx
3 | c | yyy
(2 rows)
<samp class="literal">=></samp> <kbd class="literal">SELECT * FROM t1 LEFT JOIN t2 ON t1.num = t2.num;</kbd>
num | name | num | value
-----+------+-----+-------
1 | a | 1 | xxx
2 | b | |
3 | c | 3 | yyy
(3 rows)
<samp class="literal">=></samp> <kbd class="literal">SELECT * FROM t1 LEFT JOIN t2 USING (num);</kbd>
num | name | value
-----+------+-------
1 | a | xxx
2 | b |
3 | c | yyy
(3 rows)
<samp class="literal">=></samp> <kbd class="literal">SELECT * FROM t1 RIGHT JOIN t2 ON t1.num = t2.num;</kbd>
num | name | num | value
-----+------+-----+-------
1 | a | 1 | xxx
3 | c | 3 | yyy
| | 5 | zzz
(3 rows)
<samp class="literal">=></samp> <kbd class="literal">SELECT * FROM t1 FULL JOIN t2 ON t1.num = t2.num;</kbd>
num | name | num | value
-----+------+-----+-------
1 | a | 1 | xxx
2 | b | |
3 | c | 3 | yyy
| | 5 | zzz
(4 rows)
```
用`ON`聲明的連接條件也可以包含與連接不直接相關的條件。 這種功能可能對某些查詢很有用,但是需要我們仔細想清楚。比如:
```
<samp class="literal">=></samp> <kbd class="literal">SELECT * FROM t1 LEFT JOIN t2 ON t1.num = t2.num AND t2.value = 'xxx';</kbd>
num | name | num | value
-----+------+-----+-------
1 | a | 1 | xxx
2 | b | |
3 | c | |
(3 rows)
```
請注意,將限制放在在`WHERE`子句中將會產生不同的結果:
```
<samp class="literal">=></samp> <kbd class="literal">SELECT * FROM t1 LEFT JOIN t2 ON t1.num = t2.num WHERE t2.value = 'xxx';</kbd>
num | name | num | value
-----+------+-----+-------
1 | a | 1 | xxx
(1 row)
```
這是因為限制放在`ON`子句中時是_先于_連接處理的, 而限制放在`WHERE`子句中時是_后于_連接處理的。
### 7.2.1.2\. 表和列別名
你可以給表或復雜的表引用起一個臨時的_表別名_,以便被其余的查詢引用。
要創建一個表別名,可以這樣:
```
FROM _table_reference_ AS _alias_
```
或:
```
FROM _table_reference_ _alias_
```
`AS`關鍵字沒啥特別的含義。`_alias_`可以是任意標識符。
表別名的典型應用是給長表名賦予比較短的標識,好讓連接子句更易讀一些。比如:
```
SELECT * FROM some_very_long_table_name s JOIN another_fairly_long_name a ON s.id = a.num;
```
取了別名之后就不允許再用最初的名字了。因此,這是不合法的:
```
SELECT * FROM my_table AS m WHERE my_table.a > 5; -- wrong
```
表別名主要是為了方便標記,但對于自連接卻是必須的。比如:
```
SELECT * FROM people AS mother JOIN people AS child ON mother.id = child.mother_id;
```
另外,要引用子查詢的結果也必須使用別名(參見[Section 7.2.1.3](#calibre_link-1849))。
圓括弧用于解決歧義。下面的第一個語句把別名`b`賦予第二個`my_table`表; 而第二個語句則把別名`b`賦予了連接的結果。
```
SELECT * FROM my_table AS a CROSS JOIN my_table AS b ...
SELECT * FROM (my_table AS a CROSS JOIN my_table) AS b ...
```
另外一種形式的表別名除了給表賦予別名外,還給該表的字段也賦予了別名:
```
FROM _table_reference_ [AS] _alias_ ( _column1_ [, `_column2_` [, ...]] )
```
如果聲明的字段別名比表里實際的字段少,那么后面的字段就沒有別名。 這個語法對于自連接或子查詢特別有用。
如果用這些形式中的任何一種給一個`JOIN`子句的輸出結果附加了一個別名, 那么該別名就在`JOIN`里隱藏了其原始的名字。比如:
```
SELECT a.* FROM my_table AS a JOIN your_table AS b ON ...
```
是合法 SQL ,但是:
```
SELECT a.* FROM (my_table AS a JOIN your_table AS b ON ...) AS c
```
是不合法的:別名`a`在別名`c`的外面是看不到的。
### 7.2.1.3\. 子查詢
子查詢的結果(派生表)_必須_包圍在圓括弧里并且必須賦予一個別名(參閱 [Section 7.2.1.2](#calibre_link-488))。比如:
```
FROM (SELECT * FROM table1) AS alias_name
```
這個例子等效于`FROM table1 AS alias_name`。 更有趣的例子是在子查詢里面有分組或聚集的時候, 這個時候子查詢不能歸納成一個簡單的連接。
子查詢也可以是一個`VALUES`列表:
```
FROM (VALUES ('anne', 'smith'), ('bob', 'jones'), ('joe', 'blow'))
AS names(first, last)
```
這種情況同樣也必須要取一個別名。還可以為`VALUES`列表中的字段取別名, 并且被認為是一個好習慣。更多信息參見[Section 7.7](#calibre_link-616)。
### 7.2.1.4\. 表函數
表函數是那些生成一個行集合的函數,這個集合可以是由基本數據類型(標量類型)組成, 也可以是由復合數據類型(表的行)組成。他們的用法類似一個表、視圖、或 `FROM` 子句里的子查詢。表函數返回的字段可以像一個表、視圖、或者子查詢字段那樣包含在 `SELECT`,`JOIN`,`WHERE`子句里。
如果表函數返回基本數據類型,那么單一結果字段的名字匹配函數名。 如果表函數返回復合數據類型,那么多個結果字段的名字和該類型的每個屬性的名字相同。
可以在`FROM`子句中為表函數取一個別名,也可以不取別名。 如果一個函數在`FROM`子句中沒有別名,那么將使用函數名作為結果表的名字。
一些例子:
```
CREATE TABLE foo (fooid int, foosubid int, fooname text);
CREATE FUNCTION getfoo(int) RETURNS SETOF foo AS $$
SELECT * FROM foo WHERE fooid = $1;
$$ LANGUAGE SQL;
SELECT * FROM getfoo(1) AS t1;
SELECT * FROM foo
WHERE foosubid IN (
SELECT foosubid
FROM getfoo(foo.fooid) z
WHERE z.fooid = foo.fooid
);
CREATE VIEW vw_getfoo AS SELECT * FROM getfoo(1);
SELECT * FROM vw_getfoo;
```
有時侯,把一個函數定義成根據不同的調用方法可以返回不同的字段是很有用的。 為了支持這個,表函數可以聲明為返回偽類型`record`。如果在查詢里使用這樣的函數, 那么我們必須在查詢中聲明預期的行結構,這樣系統才知道如何分析和規劃該查詢。 讓我們看看下面的例子:
```
SELECT *
FROM dblink('dbname=mydb', 'SELECT proname, prosrc FROM pg_proc')
AS t1(proname name, prosrc text)
WHERE proname LIKE 'bytea%';
```
[dblink](#calibre_link-478)函數([dblink](#calibre_link-63)模塊的一部分) 執行一個遠程的查詢。它聲明為返回`record`,因為它可能會被用于任何類型的查詢。 實際的字段集必須在調用它的查詢中聲明,這樣分析器才知道類似`*` 這樣的東西應該擴展成什么樣子。
### 7.2.1.5\. `LATERAL` 子查詢
`FROM`子句中出現的子查詢可以放在關鍵字`LATERAL`之前。 這樣就允許它們引用通過前置`FROM`條目提供的字段。(如果沒有`LATERAL`, 那么每個子查詢都被認為是獨立的并且不能交叉引用任何其他的`FROM`條目。)
`FROM`中出現的表函數也可以出現在關鍵字`LATERAL`之前, 但是對于函數來說,這個關鍵字是可選的;函數的參數在任何情況下都可以包含通過前置`FROM` 條目提供的字段。
`LATERAL`條目可以出現在`FROM`列表的頂級,或者在`JOIN`樹中。 在后者的情況下,它在`JOIN`右側時也可以參考左側的條目。
當`FROM`包含`LATERAL`交叉引用時,評估收益如下: `FROM`條目的每行或多個`FROM`條目的行組提供交叉引用的字段, `LATERAL`條目被評估為使用行或行組的字段值。結果行像平常一樣加入他們的計算行。 這些來自字段原表中的行或行組就這樣重復。
一個`LATERAL`常見的例子是:
```
SELECT * FROM foo, LATERAL (SELECT * FROM bar WHERE bar.id = foo.bar_id) ss;
```
這并不是特別有用的,因為它的結果正好和更傳統做法的相同。
```
SELECT * FROM foo, bar WHERE bar.id = foo.bar_id;
```
`LATERAL`當交叉引用字段對于加入的計算行是重要的時是主要有用的。 一個常見的應用是為一個set-returning函數提供一個參數值。例如,假設`vertices(polygon)` 返回一個多邊形的頂點坐標,我們可以識別出多邊形的頂點距離近的存儲在一個表中:
```
SELECT p1.id, p2.id, v1, v2
FROM polygons p1, polygons p2,
LATERAL vertices(p1.poly) v1,
LATERAL vertices(p2.poly) v2
WHERE (v1 <-> v2) < 10 AND p1.id != p2.id;
```
這條語句也可以寫成:
```
SELECT p1.id, p2.id, v1, v2
FROM polygons p1 CROSS JOIN LATERAL vertices(p1.poly) v1,
polygons p2 CROSS JOIN LATERAL vertices(p2.poly) v2
WHERE (v1 <-> v2) < 10 AND p1.id != p2.id;
```
或者幾個其他等價的形式。(就像之前提到的,`LATERAL`關鍵字在這個例子中不是必須的, 但是我們為了明確而是用它。)
`LEFT JOIN`對于`LATERAL`子查詢來說往往是特別有用的, 所以即使`LATERAL`子查詢不產生行,源行也將出現在結果中。例如, 如果`get_product_names()`返回一個制造商制造的產品名字, 但是一些在我們表中的制造商當前沒有生產任何產品,我們可以像下面這樣找出這些制造商:
```
SELECT m.name
FROM manufacturers m LEFT JOIN LATERAL get_product_names(m.id) pname ON true
WHERE pname IS NULL;
```
## 7.2.2\. `WHERE`子句
[_WHERE_ 子句](#calibre_link-1321)子句的語法是:
```
WHERE _search_condition_
```
這里的`_search_condition_`是一個返回類型為 `boolean` 的值表達式(參閱[Section 4.2](#calibre_link-487))。
在完成對`FROM`子句的處理之后,生成的每一行都會按照搜索條件進行檢查。 如果結果是真,那么該行保留在輸出表中,否則(也就是結果是假或NULL)就把它拋棄。 搜索條件通常至少要引用一列在`FROM`子句里生成的列,這不是必須的, 但如果不這樣的話,`WHERE`子句就沒什么意義了。
> **Note:** 內連接的連接條件既可以寫在`WHERE`子句里也可以寫在`JOIN`子句里。 比如,下面的表表達式是等效的:
>
> ```
> FROM a, b WHERE a.id = b.id AND b.val > 5
> ```
>
> 和:
>
> ```
> FROM a INNER JOIN b ON (a.id = b.id) WHERE b.val > 5
> ```
>
> 或者可能還有:
>
> ```
> FROM a NATURAL JOIN b WHERE b.val > 5
> ```
>
> 你想用哪個只是風格問題。`FROM`子句里的`JOIN` 語法可能不那么容易移植到其它產品中。即使它是在SQL標準。對于外連接而言, 我們沒有選擇:連接條件必須在`FROM`子句中完成。 外連接的`ON`或`USING`子句_不_等于`WHERE`條件, 因為它導致最終結果中行的增(那些不匹配的輸入行)和刪。
這里是一些`WHERE`子句的例子:
```
SELECT ... FROM fdt WHERE c1 > 5
SELECT ... FROM fdt WHERE c1 IN (1, 2, 3)
SELECT ... FROM fdt WHERE c1 IN (SELECT c1 FROM t2)
SELECT ... FROM fdt WHERE c1 IN (SELECT c3 FROM t2 WHERE c2 = fdt.c1 + 10)
SELECT ... FROM fdt WHERE c1 BETWEEN (SELECT c3 FROM t2 WHERE c2 = fdt.c1 + 10) AND 100
SELECT ... FROM fdt WHERE EXISTS (SELECT c1 FROM t2 WHERE c2 > fdt.c1)
```
在上面的例子里,`fdt`是從`FROM`子句中派生的表。 那些不符合`WHERE`子句的搜索條件的行將從`fdt`中刪除。 請注意我們把標量子查詢當做一個值表達式來用。就像其它查詢一樣, 子查詢里也可以使用復雜的表表達式。同時還請注意子查詢 是如何引用`fdt`的。把`c1`修飾成`fdt.c1` 只有在`c1`是該子查詢生成的列名字時才是必須的, 但修飾列名字可以增加語句的準確性(即使有時不是必須的)。 這個例子就演示了字段名字范圍如何從外層查詢擴展到它的內層查詢。
## 7.2.3\. `GROUP BY`和`HAVING`子句
在通過了`WHERE`過濾器之后,生成的輸入表可以繼續用`GROUP BY` 子句進行分組,然后用`HAVING`子句選取一些分組行。
```
SELECT _select_list_
FROM ...
[WHERE ...]
GROUP BY _grouping_column_reference_ [, `_grouping_column_reference_`]...
```
[_GROUP BY_ 子句](#calibre_link-1322)子句用于把那些所有列出的 grouping_column_reference值都相同的行聚集在一起,縮減為一行, 這樣就可以刪除輸出里的重復和/或計算應用于這些組的聚集。這些字段的列出順序無關緊要。 比如:
```
<samp class="literal">=></samp> <kbd class="literal">SELECT * FROM test1;</kbd>
x | y
---+---
a | 3
c | 2
b | 5
a | 1
(4 rows)
<samp class="literal">=></samp> <kbd class="literal">SELECT x FROM test1 GROUP BY x;</kbd>
x
---
a
b
c
(3 rows)
```
在第二個查詢里,我們不能寫成`SELECT * FROM test1 GROUP BY x`, 因為字段`y`里沒有哪個值可以和每個組關聯起來。 被分組的字段可以在選擇列表中引用是因為它們每個組都有單一的數值。
通常,如果一個表被分了組,不在`GROUP BY`中列出的字段只能在總表達式中被引用。 一個帶聚集表達式的例子是:
```
<samp class="literal">=></samp> <kbd class="literal">SELECT x, sum(y) FROM test1 GROUP BY x;</kbd>
x | sum
---+-----
a | 4
b | 5
c | 2
(3 rows)
```
這里的`sum`是一個聚集函數,它在組上計算總和。 有關可用的聚集函數的更多信息可以在[Section 9.20](#calibre_link-1641)中找到。
> **Tip:** 沒有有效的聚合表達式分組可以計算一列中不同值的設置。 這個可以通過`DISTINCT`子句來實現(參考[Section 7.3.3](#calibre_link-1812)).
這里是另外一個例子:它計算每種產品的總銷售額(而不是所有產品的總銷售額)。
```
SELECT product_id, p.name, (sum(s.units) * p.price) AS sales
FROM products p LEFT JOIN sales s USING (product_id)
GROUP BY product_id, p.name, p.price;
```
在這個例子里,字段`product_id`,`p.name` 和`p.price`必須在`GROUP BY`子句里, 因為它們都在查詢選擇列表里被引用了(但見下文)。`s.units`字段不必在 `GROUP BY`列表里,因為它只是在一個聚集表達式(`sum(...)`)里使用, 它代表一組產品的銷售總額。對于每種產品,這個查詢都返回一個該產品的總銷售額。
如果產品表是這樣設置的,就說`product_id`是主鍵, 那么它足夠在上面的例子中對`product_id`分組, 因為名字和價格將會_函數依賴_于產品ID, 這樣將不會在返回每個產品ID組時有名字和價格的分歧。
在嚴格的SQL里,`GROUP BY`只能對源表的列進行分組,但PostgreSQL 把這個擴展為也允許`GROUP BY`對選擇列表中的字段進行分組。 也允許對值表達式進行分組,而不僅僅是簡單的字段。
如果一個表已經用`GROUP BY`分了組, 然后你又只對其中的某些組感興趣,那么就可以用`HAVING`子句篩選分組。 必須像`WHERE`子句,從結果中消除組,語法是:
```
SELECT _select_list_ FROM ... [WHERE ...] GROUP BY ... HAVING _boolean_expression_
```
在`HAVING`子句中的表達式可以引用分組的表達式和未分組的表達式 (后者必須涉及一個聚集函數)。
例子:
```
<samp class="literal">=></samp> <kbd class="literal">SELECT x, sum(y) FROM test1 GROUP BY x HAVING sum(y) > 3;</kbd>
x | sum
---+-----
a | 4
b | 5
(2 rows)
<samp class="literal">=></samp> <kbd class="literal">SELECT x, sum(y) FROM test1 GROUP BY x HAVING x < 'c';</kbd>
x | sum
---+-----
a | 4
b | 5
(2 rows)
```
然后是一個更現實的例子:
```
SELECT product_id, p.name, (sum(s.units) * (p.price - p.cost)) AS profit
FROM products p LEFT JOIN sales s USING (product_id)
WHERE s.date > CURRENT_DATE - INTERVAL '4 weeks'
GROUP BY product_id, p.name, p.price, p.cost
HAVING sum(p.price * s.units) > 5000;
```
在上面的例子里,`WHERE`子句根據未分組的字段選擇數據行 (表達式只是對那些最近四周發生的銷售為真)。而`HAVING` 子句在分組之后選擇那些銷售總額超過5000的組。 請注意聚集表達式不需要在查詢中的所有地方都一樣。
如果一個查詢調用了聚合函數,但沒有`GROUP BY`子句,分組仍然發生: 結果是單一組行(或者如果單一行被`HAVING`所淘汰,那么也許沒有行)。 同樣,它包含一個`HAVING`子句,甚至沒有任何聚合函數的調用或`GROUP BY`子句。
## 7.2.4\. 窗口函數處理
如果查詢包含窗口函數(參考[Section 3.5](#calibre_link-1330),[Section 9.21](#calibre_link-1804) 和[Section 4.2.8](#calibre_link-1331)),這些函數在執行了分組、聚合和`HAVING` 過濾之后被評估。也就是說,如果查詢使用任何的聚合、`GROUP BY`或`HAVING`, 那么由窗口函數發現的行是該組行而不是從`FROM`/`WHERE`得到的原始表行。
當多個窗口函數被使用的時候,所有在它們的窗口定義里依照語法地等效于 `PARTITION BY`和`ORDER BY`子句的窗口函數保證在同一個過去的數據里被評估。 因此它們將看到同樣的排序, 即使`ORDER BY`不唯一確定一個排序。然而,不確保所做出的關于評價的功能有不同的 `PARTITION BY`或`ORDER BY`規范。(在這種情況下, 一個排序步驟通常需要在窗口函數評估之間傳遞,并且不保證行的排序看似跟`ORDER BY`等效。)
目前,窗口函數總是需要分類數據,所以查詢輸出將按照一個或另一個窗口函數的 `PARTITION BY`/`ORDER BY`子句。它不是說依賴于此。 如果你想要確保結果是按特定的方式分類那么使用顯式的頂級ORDER BY子句。
- 前言
- 何為PostgreSQL?
- PostgreSQL簡史
- 格式約定
- 更多信息
- 臭蟲匯報指導
- I. 教程
- Chapter 1. 從頭開始
- 1.1. 安裝
- 1.2. 體系基本概念
- 1.3. 創建一個數據庫
- 1.4. 訪問數據庫
- Chapter 2. SQL語言
- 2.1. 介紹
- 2.2. 概念
- 2.3. 創建新表
- 2.4. 向表中添加行
- 2.5. 查詢一個表
- 2.6. 在表間連接
- 2.7. 聚集函數
- 2.8. 更新
- 2.9. 刪除
- Chapter 3. 高級特性
- 3.1. 介紹
- 3.2. 視圖
- 3.3. 外鍵
- 3.4. 事務
- 3.5. 窗口函數
- 3.6. 繼承
- 3.7. 結論
- II. SQL 語言
- Chapter 4. SQL語法
- 4.1. 詞法結構
- 4.2. 值表達式
- 4.3. 調用函數
- Chapter 5. 數據定義
- 5.1. 表的基本概念
- 5.2. 缺省值
- 5.3. 約束
- 5.4. 系統字段
- 5.5. 修改表
- 5.6. 權限
- 5.7. 模式
- 5.8. 繼承
- 5.9. 分區
- 5.10. 外部數據
- 5.11. 其它數據庫對象
- 5.12. 依賴性跟蹤
- Chapter 6. 數據操作
- 6.1. 插入數據
- 6.2. 更新數據
- 6.3. 刪除數據
- Chapter 7. 查詢
- 7.1. 概述
- 7.2. 表表達式
- 7.3. 選擇列表
- 7.4. 組合查詢
- 7.5. 行排序
- 7.6. LIMIT和OFFSET
- 7.7. VALUES列表
- 7.8. WITH 查詢 (通用表表達式)
- Chapter 8. 數據類型
- 8.1. 數值類型
- 8.2. 貨幣類型
- 8.3. 字符類型
- 8.4. 二進制數據類型
- 8.5. 日期/時間類型
- 8.6. 布爾類型
- 8.7. 枚舉類型
- 8.8. 幾何類型
- 8.9. 網絡地址類型
- 8.10. 位串類型
- 8.11. 文本搜索類型
- 8.12. UUID 類型
- 8.13. XML 類型
- 8.14. JSON 類型
- 8.15. Arrays
- 8.16. 復合類型
- 8.17. 范圍類型
- 8.18. 對象標識符類型
- 8.19. 偽類型
- Chapter 9. 函數和操作符
- 9.1. 邏輯操作符
- 9.2. 比較操作符
- 9.3. 數學函數和操作符
- 9.4. 字符串函數和操作符
- 9.5. 二進制字符串函數和操作符
- 9.6. 位串函數和操作符
- 9.7. 模式匹配
- 9.8. 數據類型格式化函數
- 9.9. 時間/日期函數和操作符
- 9.10. 支持枚舉函數
- 9.11. 幾何函數和操作符
- 9.12. 網絡地址函數和操作符
- 9.13. 文本檢索函數和操作符
- 9.14. XML 函數
- 9.15. JSON 函數和操作符
- 9.16. 序列操作函數
- 9.17. 條件表達式
- 9.18. 數組函數和操作符
- 9.19. 范圍函數和操作符
- 9.20. 聚集函數
- 9.21. 窗口函數
- 9.22. 子查詢表達式
- 9.23. 行和數組比較
- 9.24. 返回集合的函數
- 9.25. 系統信息函數
- 9.26. 系統管理函數
- 9.27. 觸發器函數
- 9.28. 事件觸發函數
- Chapter 10. 類型轉換
- 10.1. 概述
- 10.2. 操作符
- 10.3. 函數
- 10.4. 值存儲
- 10.5. UNION, CASE 和相關構造
- Chapter 11. 索引
- 11.1. 介紹
- 11.2. 索引類型
- 11.3. 多字段索引
- 11.4. 索引和ORDER BY
- 11.5. 組合多個索引
- 11.6. 唯一索引
- 11.7. 表達式上的索引
- 11.8. 部分索引
- 11.9. 操作符類和操作符族
- 11.10. 索引和排序
- 11.11. 檢查索引的使用
- Chapter 12. 全文檢索
- 12.1. 介紹
- 12.2. 表和索引
- 12.3. 控制文本搜索
- 12.4. 附加功能
- 12.5. 解析器
- 12.6. 詞典
- 12.7. 配置實例
- 12.8. 測試和調試文本搜索
- 12.9. GiST和GIN索引類型
- 12.10. psql支持
- 12.11. 限制
- 12.12. 來自8.3之前文本搜索的遷移
- Chapter 13. 并發控制
- 13.1. 介紹
- 13.2. 事務隔離
- 13.3. 明確鎖定
- 13.4. 應用層數據完整性檢查
- 13.5. 鎖和索引
- Chapter 14. 性能提升技巧
- 14.1. 使用EXPLAIN
- 14.2. 規劃器使用的統計信息
- 14.3. 用明確的JOIN控制規劃器
- 14.4. 向數據庫中添加記錄
- 14.5. 非持久性設置
- III. 服務器管理
- Chapter 15. 源碼安裝
- 15.1. 簡版
- 15.2. 要求
- 15.3. 獲取源碼
- 15.4. 安裝過程
- 15.5. 安裝后設置
- 15.6. 支持平臺
- 15.7. 特定平臺注意事項
- Chapter 16. Windows下用源代碼安裝
- 16.1. 用Visual C++或Microsoft Windows SDK編譯
- 16.2. 用Visual C++或 Borland C++編譯 libpq
- Chapter 17. 服務器設置和操作
- 17.1. PostgreSQL用戶賬戶
- 17.2. 創建數據庫集群
- 17.3. 啟動數據庫服務器
- 17.4. 管理內核資源
- 17.5. 關閉服務器
- 17.6. 升級一個 PostgreSQL 集群
- 17.7. 防止服務器欺騙
- 17.8. 加密選項
- 17.9. 用 SSL 進行安全的 TCP/IP 連接
- 17.10. 用SSH隧道進行安全 TCP/IP 連接
- 17.11. 在Windows上注冊事件日志
- Chapter 18. 服務器配置
- 18.1. 設置參數
- 18.2. 文件位置
- 18.3. 連接和認證
- 18.4. 資源消耗
- 18.5. 預寫式日志
- 18.6. 復制
- 18.7. 查詢規劃
- 18.8. 錯誤報告和日志
- 18.9. 運行時統計
- 18.10. 自動清理
- 18.11. 客戶端連接缺省
- 18.12. 鎖管理
- 18.13. 版本和平臺兼容性
- 18.14. Error Handling
- 18.15. 預置選項
- 18.16. 自定義選項
- 18.17. 開發人員選項
- 18.18. 短選項
- Chapter 19. 用戶認證
- 19.1. pg_hba.conf文件
- 19.2. 用戶名映射
- 19.3. 認證方法
- 19.4. 用戶認證
- Chapter 20. 數據庫角色
- 20.1. 數據庫角色
- 20.2. 角色屬性
- 20.3. 角色成員
- 20.4. 函數和觸發器安全
- Chapter 21. 管理數據庫
- 21.1. 概述
- 21.2. 創建一個數據庫
- 21.3. 模板數據庫
- 21.4. 數據庫配置
- 21.5. 刪除數據庫
- 21.6. 表空間
- Chapter 22. 區域
- 22.1. 區域支持
- 22.2. 排序規則支持
- 22.3. 字符集支持
- Chapter 23. 日常數據庫維護工作
- 23.1. 日常清理
- 23.2. 經常重建索引
- 23.3. 日志文件維護
- Chapter 24. 備份與恢復
- 24.1. SQL轉儲
- 24.2. 文件系統級別備份
- 24.3. 在線備份以及即時恢復(PITR)
- Chapter 25. 高可用性與負載均衡,復制
- 25.1. 不同解決方案的比較
- 25.2. 日志傳送備份服務器
- 25.3. 失效切換
- 25.4. 日志傳送的替代方法
- 25.5. 熱備
- Chapter 26. 恢復配置
- 26.1. 歸檔恢復設置
- 26.2. 恢復目標設置
- 26.3. 備用服務器設置
- Chapter 27. 監控數據庫的活動
- 27.1. 標準Unix工具
- 27.2. 統計收集器
- 27.3. 查看鎖
- 27.4. 動態跟蹤
- Chapter 28. 監控磁盤使用情況
- 28.1. 判斷磁盤的使用量
- 28.2. 磁盤滿導致的失效
- Chapter 29. 可靠性和預寫式日志
- 29.1. 可靠性
- 29.2. 預寫式日志(WAL)
- 29.3. 異步提交
- 29.4. WAL 配置
- 29.5. WAL 內部
- Chapter 30. 回歸測試
- 30.1. 運行測試
- 30.2. 測試評估
- 30.3. 平臺相關的比較文件
- 30.4. 測試覆蓋率檢查
- IV. 客戶端接口
- Chapter 31. libpq - C 庫
- 31.1. 數據庫連接控制函數
- 31.2. 連接狀態函數
- 31.3. 命令執行函數
- 31.4. 異步命令處理
- 31.5. 逐行檢索查詢結果
- 31.6. 取消正在處理的查詢
- 31.7. 捷徑接口
- 31.8. 異步通知
- 31.9. 與COPY命令相關的函數
- 31.10. 控制函數
- 31.11. 各種函數
- 31.12. 注意信息處理
- 31.13. 事件系統
- 31.14. 環境變量
- 31.15. 口令文件
- 31.16. 連接服務的文件
- 31.17. LDAP查找連接參數
- 31.18. SSL 支持
- 31.19. 在多線程程序里的行為
- 31.20. 制作libpq程序
- 31.21. 例子程序
- Chapter 32. 大對象
- 32.1. 介紹
- 32.2. 實現特點
- 32.3. 客戶端接口
- 32.4. 服務器端函數
- 32.5. 例子程序
- Chapter 33. ECPG - 在C中嵌入SQL
- 33.1. 概念
- 33.2. 管理數據庫連接
- 33.3. 運行SQL命令
- 33.4. 使用宿主變量
- 33.5. 動態SQL
- 33.6. pgtypes 庫
- 33.7. 使用描述符范圍
- 33.8. 錯誤處理
- 33.9. 預處理器指令
- 33.10. 處理嵌入的SQL程序
- 33.11. 庫函數
- 33.12. 大對象
- 33.13. C++應用程序
- 33.14. 嵌入的SQL命令
- ALLOCATE DESCRIPTOR
- CONNECT
- DEALLOCATE DESCRIPTOR
- DECLARE
- DESCRIBE
- DISCONNECT
- EXECUTE IMMEDIATE
- GET DESCRIPTOR
- OPEN
- PREPARE
- SET AUTOCOMMIT
- SET CONNECTION
- SET DESCRIPTOR
- TYPE
- VAR
- WHENEVER
- 33.15. Informix兼容模式
- 33.16. 內部
- Chapter 34. 信息模式
- 34.1. 關于這個模式
- 34.2. 數據類型
- 34.3. information_schema_catalog_name
- 34.4. administrable_role_authorizations
- 34.5. applicable_roles
- 34.6. attributes
- 34.7. character_sets
- 34.8. check_constraint_routine_usage
- 34.9. check_constraints
- 34.10. collations
- 34.11. collation_character_set_applicability
- 34.12. column_domain_usage
- 34.13. column_options
- 34.14. column_privileges
- 34.15. column_udt_usage
- 34.16. columns
- 34.17. constraint_column_usage
- 34.18. constraint_table_usage
- 34.19. data_type_privileges
- 34.20. domain_constraints
- 34.21. domain_udt_usage
- 34.22. domains
- 34.23. element_types
- 34.24. enabled_roles
- 34.25. foreign_data_wrapper_options
- 34.26. foreign_data_wrappers
- 34.27. foreign_server_options
- 34.28. foreign_servers
- 34.29. foreign_table_options
- 34.30. foreign_tables
- 34.31. key_column_usage
- 34.32. parameters
- 34.33. referential_constraints
- 34.34. role_column_grants
- 34.35. role_routine_grants
- 34.36. role_table_grants
- 34.37. role_udt_grants
- 34.38. role_usage_grants
- 34.39. routine_privileges
- 34.40. routines
- 34.41. schemata
- 34.42. sequences
- 34.43. sql_features
- 34.44. sql_implementation_info
- 34.45. sql_languages
- 34.46. sql_packages
- 34.47. sql_parts
- 34.48. sql_sizing
- 34.49. sql_sizing_profiles
- 34.50. table_constraints
- 34.51. table_privileges
- 34.52. tables
- 34.53. triggered_update_columns
- 34.54. triggers
- 34.55. udt_privileges
- 34.56. usage_privileges
- 34.57. user_defined_types
- 34.58. user_mapping_options
- 34.59. user_mappings
- 34.60. view_column_usage
- 34.61. view_routine_usage
- 34.62. view_table_usage
- 34.63. views
- V. 服務器端編程
- Chapter 35. 擴展SQL
- 35.1. 擴展性是如何實現的
- 35.2. PostgreSQL類型系統
- 35.3. 用戶定義的函數
- 35.4. 查詢語言(SQL)函數
- 35.5. 函數重載
- 35.6. 函數易失性范疇
- 35.7. 過程語言函數
- 35.8. 內部函數
- 35.9. C-語言函數
- 35.10. 用戶定義聚集
- 35.11. 用戶定義類型
- 35.12. 用戶定義操作符
- 35.13. 操作符優化信息
- 35.14. 擴展索引接口
- 35.15. 包裝相關對象到一個擴展
- 35.16. 擴展基礎設施建設
- Chapter 36. 觸發器
- 36.1. 觸發器行為概述
- 36.2. 數據改變的可視性
- 36.3. 用C寫觸發器
- 36.4. 一個完整的觸發器例子
- Chapter 37. 事件觸發器
- 37.1. 事件觸發器行為的概述
- 37.2. 事件觸發器觸發矩陣
- 37.3. 用C編寫事件觸發器函數
- 37.4. 一個完整的事件觸發器的例子
- Chapter 38. 規則系統
- 38.1. 查詢樹
- 38.2. 視圖和規則系統
- 38.3. 物化視圖
- 38.4. 在 INSERT, UPDATE, 和 DELETE上的規則
- 38.5. 規則和權限
- 38.6. 規則和命令狀態
- 38.7. 規則與觸發器的比較
- Chapter 39. 過程語言
- 39.1. 安裝過程語言
- Chapter 40. PL/pgSQL - SQL過程語言
- 40.1. 概述
- 40.2. PL/pgSQL的結構
- 40.3. 聲明
- 40.4. 表達式
- 40.5. 基本語句
- 40.6. 控制結構
- 40.7. 游標
- 40.8. 錯誤和消息
- 40.9. 觸發器過程
- 40.10. 在后臺下的PL/pgSQL
- 40.11. 開發PL/pgSQL的一些提示
- 40.12. 從Oracle PL/SQL進行移植
- Chapter 41. PL/Tcl - Tcl 過程語言
- 41.1. 概述
- 41.2. PL/Tcl 函數和參數
- 41.3. PL/Tcl里的數據值
- 41.4. PL/Tcl里的全局量
- 41.5. 在PL/Tcl里訪問數據庫
- 41.6. PL/Tcl里的觸發器過程
- 41.7. 模塊和unknown的命令
- 41.8. Tcl 過程名字
- Chapter 42. PL/Perl - Perl 過程語言
- 42.1. PL/Perl 函數和參數
- 42.2. PL/Perl里的數據值
- 42.3. 內置函數
- 42.4. PL/Perl里的全局變量
- 42.5. 可信的和不可信的 PL/Perl
- 42.6. PL/Perl 觸發器
- 42.7. 后臺PL/Perl
- Chapter 43. PL/Python - Python 過程語言
- 43.1. Python 2 vs. Python 3
- 43.2. PL/Python Functions
- 43.3. Data Values
- 43.4. Sharing Data
- 43.5. Anonymous Code Blocks
- 43.6. Trigger Functions
- 43.7. Database Access
- 43.8. Explicit Subtransactions
- 43.9. Utility Functions
- 43.10. Environment Variables
- Chapter 44. 服務器編程接口
- 44.1. 接口函數
- SPI_connect
- SPI_finish
- SPI_push
- SPI_pop
- SPI_execute
- SPI_exec
- SPI_execute_with_args
- SPI_prepare
- SPI_prepare_cursor
- SPI_prepare_params
- SPI_getargcount
- SPI_getargtypeid
- SPI_is_cursor_plan
- SPI_execute_plan
- SPI_execute_plan_with_paramlist
- SPI_execp
- SPI_cursor_open
- SPI_cursor_open_with_args
- SPI_cursor_open_with_paramlist
- SPI_cursor_find
- SPI_cursor_fetch
- SPI_cursor_move
- SPI_scroll_cursor_fetch
- SPI_scroll_cursor_move
- SPI_cursor_close
- SPI_keepplan
- SPI_saveplan
- 44.2. 接口支持函數
- SPI_fname
- SPI_fnumber
- SPI_getvalue
- SPI_getbinval
- SPI_gettype
- SPI_gettypeid
- SPI_getrelname
- SPI_getnspname
- 44.3. 內存管理
- SPI_palloc
- SPI_repalloc
- SPI_pfree
- SPI_copytuple
- SPI_returntuple
- SPI_modifytuple
- SPI_freetuple
- SPI_freetuptable
- SPI_freeplan
- 44.4. 數據改變的可視性
- 44.5. 例子
- Chapter 45. 后臺工作進程
- VI. 參考手冊
- I. SQL 命令
- ABORT
- ALTER AGGREGATE
- ALTER COLLATION
- ALTER CONVERSION
- ALTER DATABASE
- ALTER DEFAULT PRIVILEGES
- ALTER DOMAIN
- ALTER EXTENSION
- ALTER EVENT TRIGGER
- ALTER FOREIGN DATA WRAPPER
- ALTER FOREIGN TABLE
- ALTER FUNCTION
- ALTER GROUP
- ALTER INDEX
- ALTER LANGUAGE
- ALTER LARGE OBJECT
- ALTER MATERIALIZED VIEW
- ALTER OPERATOR
- ALTER OPERATOR CLASS
- ALTER OPERATOR FAMILY
- ALTER ROLE
- ALTER RULE
- ALTER SCHEMA
- ALTER SEQUENCE
- ALTER SERVER
- ALTER TABLE
- ALTER TABLESPACE
- ALTER TEXT SEARCH CONFIGURATION
- ALTER TEXT SEARCH DICTIONARY
- ALTER TEXT SEARCH PARSER
- ALTER TEXT SEARCH TEMPLATE
- ALTER TRIGGER
- ALTER TYPE
- ALTER USER
- ALTER USER MAPPING
- ALTER VIEW
- ANALYZE
- BEGIN
- CHECKPOINT
- CLOSE
- CLUSTER
- COMMENT
- COMMIT
- COMMIT PREPARED
- COPY
- CREATE AGGREGATE
- CREATE CAST
- CREATE COLLATION
- CREATE CONVERSION
- CREATE DATABASE
- CREATE DOMAIN
- CREATE EXTENSION
- CREATE EVENT TRIGGER
- CREATE FOREIGN DATA WRAPPER
- CREATE FOREIGN TABLE
- CREATE FUNCTION
- CREATE GROUP
- CREATE INDEX
- CREATE LANGUAGE
- CREATE MATERIALIZED VIEW
- CREATE OPERATOR
- CREATE OPERATOR CLASS
- CREATE OPERATOR FAMILY
- CREATE ROLE
- CREATE RULE
- CREATE SCHEMA
- CREATE SEQUENCE
- CREATE SERVER
- CREATE TABLE
- CREATE TABLE AS
- CREATE TABLESPACE
- CREATE TEXT SEARCH CONFIGURATION
- CREATE TEXT SEARCH DICTIONARY
- CREATE TEXT SEARCH PARSER
- CREATE TEXT SEARCH TEMPLATE
- CREATE TRIGGER
- CREATE TYPE
- CREATE USER
- CREATE USER MAPPING
- CREATE VIEW
- DEALLOCATE
- DECLARE
- DELETE
- DISCARD
- DO
- DROP AGGREGATE
- DROP CAST
- DROP COLLATION
- DROP CONVERSION
- DROP DATABASE
- DROP DOMAIN
- DROP EXTENSION
- DROP EVENT TRIGGER
- DROP FOREIGN DATA WRAPPER
- DROP FOREIGN TABLE
- DROP FUNCTION
- DROP GROUP
- DROP INDEX
- DROP LANGUAGE
- DROP MATERIALIZED VIEW
- DROP OPERATOR
- DROP OPERATOR CLASS
- DROP OPERATOR FAMILY
- DROP OWNED
- DROP ROLE
- DROP RULE
- DROP SCHEMA
- DROP SEQUENCE
- DROP SERVER
- DROP TABLE
- DROP TABLESPACE
- DROP TEXT SEARCH CONFIGURATION
- DROP TEXT SEARCH DICTIONARY
- DROP TEXT SEARCH PARSER
- DROP TEXT SEARCH TEMPLATE
- DROP TRIGGER
- DROP TYPE
- DROP USER
- DROP USER MAPPING
- DROP VIEW
- END
- EXECUTE
- EXPLAIN
- FETCH
- GRANT
- INSERT
- LISTEN
- LOAD
- LOCK
- MOVE
- NOTIFY
- PREPARE
- PREPARE TRANSACTION
- REASSIGN OWNED
- REFRESH MATERIALIZED VIEW
- REINDEX
- RELEASE SAVEPOINT
- RESET
- REVOKE
- ROLLBACK
- ROLLBACK PREPARED
- ROLLBACK TO SAVEPOINT
- SAVEPOINT
- SECURITY LABEL
- SELECT
- SELECT INTO
- SET
- SET CONSTRAINTS
- SET ROLE
- SET SESSION AUTHORIZATION
- SET TRANSACTION
- SHOW
- START TRANSACTION
- TRUNCATE
- UNLISTEN
- UPDATE
- VACUUM
- VALUES
- II. PostgreSQL 客戶端應用程序
- clusterdb
- createdb
- createlang
- createuser
- dropdb
- droplang
- dropuser
- ecpg
- pg_basebackup
- pg_config
- pg_dump
- pg_dumpall
- pg_isready
- pg_receivexlog
- pg_restore
- psql
- reindexdb
- vacuumdb
- III. PostgreSQL 服務器應用程序
- initdb
- pg_controldata
- pg_ctl
- pg_resetxlog
- postgres
- postmaster
- VII. 內部
- Chapter 46. PostgreSQL內部概述
- 46.1. 查詢經過的路徑
- 46.2. 連接是如何建立起來的
- 46.3. 分析器階段
- 46.4. PostgreSQL規則系統
- 46.5. 規劃器/優化器
- 46.6. 執行器
- Chapter 47. 系統表
- 47.1. 概述
- 47.2. pg_aggregate
- 47.3. pg_am
- 47.4. pg_amop
- 47.5. pg_amproc
- 47.6. pg_attrdef
- 47.7. pg_attribute
- 47.8. pg_authid
- 47.9. pg_auth_members
- 47.10. pg_cast
- 47.11. pg_class
- 47.12. pg_event_trigger
- 47.13. pg_constraint
- 47.14. pg_collation
- 47.15. pg_conversion
- 47.16. pg_database
- 47.17. pg_db_role_setting
- 47.18. pg_default_acl
- 47.19. pg_depend
- 47.20. pg_description
- 47.21. pg_enum
- 47.22. pg_extension
- 47.23. pg_foreign_data_wrapper
- 47.24. pg_foreign_server
- 47.25. pg_foreign_table
- 47.26. pg_index
- 47.27. pg_inherits
- 47.28. pg_language
- 47.29. pg_largeobject
- 47.30. pg_largeobject_metadata
- 47.31. pg_namespace
- 47.32. pg_opclass
- 47.33. pg_operator
- 47.34. pg_opfamily
- 47.35. pg_pltemplate
- 47.36. pg_proc
- 47.37. pg_range
- 47.38. pg_rewrite
- 47.39. pg_seclabel
- 47.40. pg_shdepend
- 47.41. pg_shdescription
- 47.42. pg_shseclabel
- 47.43. pg_statistic
- 47.44. pg_tablespace
- 47.45. pg_trigger
- 47.46. pg_ts_config
- 47.47. pg_ts_config_map
- 47.48. pg_ts_dict
- 47.49. pg_ts_parser
- 47.50. pg_ts_template
- 47.51. pg_type
- 47.52. pg_user_mapping
- 47.53. 系統視圖
- 47.54. pg_available_extensions
- 47.55. pg_available_extension_versions
- 47.56. pg_cursors
- 47.57. pg_group
- 47.58. pg_indexes
- 47.59. pg_locks
- 47.60. pg_matviews
- 47.61. pg_prepared_statements
- 47.62. pg_prepared_xacts
- 47.63. pg_roles
- 47.64. pg_rules
- 47.65. pg_seclabels
- 47.66. pg_settings
- 47.67. pg_shadow
- 47.68. pg_stats
- 47.69. pg_tables
- 47.70. pg_timezone_abbrevs
- 47.71. pg_timezone_names
- 47.72. pg_user
- 47.73. pg_user_mappings
- 47.74. pg_views
- Chapter 48. 前/后端協議
- 48.1. 概要
- 48.2. 消息流
- 48.3. 流復制協議
- 48.4. 消息數據類型
- 48.5. 消息格式
- 48.6. 錯誤和通知消息字段
- 48.7. 自協議 2.0 以來的變化的概述
- Chapter 49. PostgreSQL 編碼約定
- 49.1. 格式
- 49.2. 報告服務器里的錯誤
- 49.3. 錯誤消息風格指導
- Chapter 50. 本地語言支持
- 50.1. 寄語翻譯家
- 50.2. 寄語程序員
- Chapter 51. 書寫一個過程語言處理器
- Chapter 52. 寫一個外數據包
- 52.1. 外數據封裝函數
- 52.2. 外數據封裝回調程序
- 52.3. 外數據封裝輔助函數
- 52.4. 外數據封裝查詢規劃
- Chapter 53. 基因查詢優化器
- 53.1. 作為復雜優化問題的查詢處理
- 53.2. 基因算法
- 53.3. PostgreSQL 里的基因查詢優化(GEQO)
- 53.4. 進一步閱讀
- Chapter 54. 索引訪問方法接口定義
- 54.1. 索引的系統表記錄
- 54.2. 索引訪問方法函數
- 54.3. 索引掃描
- 54.4. 索引鎖的考量
- 54.5. 索引唯一性檢查
- 54.6. 索引開銷估計函數
- Chapter 55. GiST索引
- 55.1. 介紹
- 55.2. 擴展性
- 55.3. 實現
- 55.4. 例
- Chapter 56. SP-GiST索引
- 56.1. 介紹
- 56.2. 擴展性
- 56.3. 實現
- 56.4. 例
- Chapter 57. GIN索引
- 57.1. 介紹
- 57.2. 擴展性
- 57.3. 實現
- 57.4. GIN提示與技巧
- 57.5. 限制
- 57.6. 例子
- Chapter 58. 數據庫物理存儲
- 58.1. 數據庫文件布局
- 58.2. TOAST
- 58.3. 自由空間映射
- 58.4. 可見映射
- 58.5. 初始化分支
- 58.6. 數據庫分頁文件
- Chapter 59. BKI后端接口
- 59.1. BKI 文件格式
- 59.2. BKI 命令
- 59.3. 系統初始化的BKI文件的結構
- 59.4. 例子
- Chapter 60. 規劃器如何使用統計信息
- 60.1. 行預期的例子
- VIII. 附錄
- Appendix A. PostgreSQL 錯誤代碼
- Appendix B. 日期/時間支持
- B.1. 日期/時間輸入解析
- B.2. 日期/時間關鍵字
- B.3. 日期/時間配置文件
- B.4. 單位歷史
- Appendix C. SQL關鍵字
- Appendix D. SQL兼容性
- D.1. 支持的特性
- D.2. 不支持的特性
- Appendix E. 版本說明
- E.1. 版本 9.3.1
- E.2. 版本 9.3
- E.3. 版本9.2.5
- E.4. 版本9.2.4
- E.5. 版本9.2.3
- E.6. 版本9.2.2
- E.7. 版本9.2.1
- E.8. 版本9.2
- E.9. 發布9.1.10
- E.10. 發布9.1.9
- E.11. 發布9.1.8
- E.12. 發布9.1.7
- E.13. 發布9.1.6
- E.14. 發布9.1.5
- E.15. 發布9.1.4
- E.16. 發布9.1.3
- E.17. 發布9.1.2
- E.18. 發布9.1.1
- E.19. 發布9.1
- E.20. 版本 9.0.14
- E.21. 版本 9.0.13
- E.22. 版本 9.0.12
- E.23. 版本 9.0.11
- E.24. 版本 9.0.10
- E.25. 版本 9.0.9
- E.26. 版本 9.0.8
- E.27. 版本 9.0.7
- E.28. 版本 9.0.6
- E.29. 版本 9.0.5
- E.30. 版本 9.0.4
- E.31. 版本 9.0.3
- E.32. 版本 9.0.2
- E.33. 版本 9.0.1
- E.34. 版本 9.0
- E.35. 發布8.4.18
- E.36. 發布8.4.17
- E.37. 發布8.4.16
- E.38. 發布8.4.15
- E.39. 發布8.4.14
- E.40. 發布8.4.13
- E.41. 發布8.4.12
- E.42. 發布8.4.11
- E.43. 發布8.4.10
- E.44. 發布8.4.9
- E.45. 發布8.4.8
- E.46. 發布8.4.7
- E.47. 發布8.4.6
- E.48. 發布8.4.5
- E.49. 發布8.4.4
- E.50. 發布8.4.3
- E.51. 發布8.4.2
- E.52. 發布8.4.1
- E.53. 發布8.4
- E.54. 發布8.3.23
- E.55. 發布8.3.22
- E.56. 發布8.3.21
- E.57. 發布8.3.20
- E.58. 發布8.3.19
- E.59. 發布8.3.18
- E.60. 發布8.3.17
- E.61. 發布8.3.16
- E.62. 發布8.3.15
- E.63. 發布8.3.14
- E.64. 發布8.3.13
- E.65. 發布8.3.12
- E.66. 發布8.3.11
- E.67. 發布8.3.10
- E.68. 發布8.3.9
- E.69. 發布8.3.8
- E.70. 發布8.3.7
- E.71. 發布8.3.6
- E.72. 發布8.3.5
- E.73. 發布8.3.4
- E.74. 發布8.3.3
- E.75. 發布8.3.2
- E.76. 發布8.3.1
- E.77. 發布8.3
- E.78. 版本 8.2.23
- E.79. 版本 8.2.22
- E.80. 版本 8.2.21
- E.81. 版本 8.2.20
- E.82. 版本 8.2.19
- E.83. 版本 8.2.18
- E.84. 版本 8.2.17
- E.85. 版本 8.2.16
- E.86. 版本 8.2.15
- E.87. 版本 8.2.14
- E.88. 版本 8.2.13
- E.89. 版本 8.2.12
- E.90. 版本 8.2.11
- E.91. 版本 8.2.10
- E.92. 版本 8.2.9
- E.93. 版本 8.2.8
- E.94. 版本 8.2.7
- E.95. 版本 8.2.6
- E.96. 版本 8.2.5
- E.97. 版本 8.2.4
- E.98. 版本 8.2.3
- E.99. 版本 8.2.2
- E.100. 版本 8.2.1
- E.101. 版本 8.2
- E.102. 版本 8.1.23
- E.103. 版本 8.1.22
- E.104. 版本 8.1.21
- E.105. 版本 8.1.20
- E.106. 版本 8.1.19
- E.107. 版本 8.1.18
- E.108. 版本 8.1.17
- E.109. 版本 8.1.16
- E.110. 版本 8.1.5
- E.111. 版本 8.1.14
- E.112. 版本 8.1.13
- E.113. 版本 8.1.12
- E.114. 版本 8.1.11
- E.115. 版本 8.1.10
- E.116. 版本 8.1.9
- E.117. 版本 8.1.8
- E.118. 版本 8.1.7
- E.119. 版本 8.1.6
- E.120. 版本 8.1.5
- E.121. 版本 8.1.4
- E.122. 版本 8.1.3
- E.123. 版本 8.1.2
- E.124. 版本 8.1.1
- E.125. 版本 8.1
- E.126. 版本 8.0.26
- E.127. 版本 8.0.25
- E.128. 版本 8.0.24
- E.129. 版本 8.0.23
- E.130. 版本 8.0.22
- E.131. 版本 8.0.21
- E.132. 版本 8.0.20
- E.133. 版本 8.0.19
- E.134. 版本 8.0.18
- E.135. 版本 8.0.17
- E.136. 版本 8.0.16
- E.137. 版本 8.0.15
- E.138. 版本 8.0.14
- E.139. 版本 8.0.13
- E.140. 版本 8.0.12
- E.141. 版本 8.0.11
- E.142. 版本 8.0.10
- E.143. 版本 8.0.9
- E.144. 版本 8.0.8
- E.145. 版本 8.0.7
- E.146. 版本 8.0.6
- E.147. 版本 8.0.5
- E.148. 版本 8.0.4
- E.149. 版本 8.0.3
- E.150. 版本 8.0.2
- E.151. 版本 8.0.1
- E.152. 版本 8.0.0
- E.153. 版本 7.4.30
- E.154. 版本 7.4.29
- E.155. 版本 7.4.28
- E.156. 版本 7.4.27
- E.157. 版本 7.4.26
- E.158. 版本 7.4.25
- E.159. 版本 7.4.24
- E.160. 版本 7.4.23
- E.161. 版本 7.4.22
- E.162. 版本 7.4.21
- E.163. 版本 7.4.20
- E.164. 版本 7.4.19
- E.165. 版本 7.4.18
- E.166. 版本 7.4.17
- E.167. 版本 7.4.16
- E.168. 版本 7.4.15
- E.169. 版本 7.4.14
- E.170. 版本 7.4.13
- E.171. 版本 7.4.12
- E.172. 版本 7.4.11
- E.173. 版本 7.4.10
- E.174. 版本 7.4.9
- E.175. 版本 7.4.8
- E.176. 版本 7.4.7
- E.177. 版本 7.4.6
- E.178. 版本 7.4.3
- E.179. 版本 7.4.4
- E.180. 版本 7.4.3
- E.181. 版本 7.4.2
- E.182. 版本 7.4.1
- E.183. 版本 7.4
- E.184. 版本 7.3.21
- E.185. 版本 7.3.20
- E.186. 版本 7.3.19
- E.187. 版本 7.3.18
- E.188. 版本 7.3.17
- E.189. 版本 7.3.16
- E.190. 版本 7.3.15
- E.191. 版本 7.3.14
- E.192. 版本 7.3.13
- E.193. 版本 7.3.12
- E.194. 版本 7.3.11
- E.195. 版本 7.3.10
- E.196. 版本 7.3.9
- E.197. 版本 7.3.8
- E.198. 版本 7.3.7
- E.199. 版本 7.3.6
- E.200. 版本 7.3.5
- E.201. 版本 7.3.4
- E.202. 版本 7.3.3
- E.203. 版本 7.3.2
- E.204. 版本 7.3.1
- E.205. 版本 7.3
- E.206. 版本 7.2.8
- E.207. 版本 7.2.7
- E.208. 版本 7.2.6
- E.209. 版本 7.2.5
- E.210. 版本 7.2.4
- E.211. 版本 7.2.3
- E.212. 版本 7.2.2
- E.213. 版本 7.2.1
- E.214. 版本 7.2
- E.215. 版本 7.1.3
- E.216. 版本 7.1.2
- E.217. 版本 7.1.1
- E.218. 版本 7.1
- E.219. 版本 7.0.3
- E.220. 版本 7.0.2
- E.221. 版本 7.0.1
- E.222. 版本 7.0
- E.223. 版本 6.5.3
- E.224. 版本 6.5.2
- E.225. 版本 6.5.1
- E.226. 版本 6.5
- E.227. 版本 6.4.2
- E.228. 版本 6.4.1
- E.229. 版本 6.4
- E.230. 版本 6.3.2
- E.231. 版本 6.3.1
- E.232. 版本 6.3
- E.233. 版本 6.2.1
- E.234. 版本 6.2
- E.235. 版本 6.1.1
- E.236. 版本 6.1
- E.237. 版本 6.0
- E.238. 版本 1.09
- E.239. 版本 1.02
- E.240. 版本 1.01
- E.241. 版本 1.0
- E.242. Postgres95 版本 0.03
- E.243. Postgres95 版本 0.02
- E.244. Postgres95 版本 0.01
- Appendix F. 額外提供的模塊
- F.1. adminpack
- F.2. auth_delay
- F.3. auto_explain
- F.4. btree_gin
- F.5. btree_gist
- F.6. chkpass
- F.7. citext
- F.8. cube
- F.9. dblink
- dblink_connect
- dblink_connect_u
- dblink_disconnect
- dblink
- dblink_exec
- dblink_open
- dblink_fetch
- dblink_close
- dblink_get_connections
- dblink_error_message
- dblink_send_query
- dblink_is_busy
- dblink_get_notify
- dblink_get_result
- dblink_cancel_query
- dblink_get_pkey
- dblink_build_sql_insert
- dblink_build_sql_delete
- dblink_build_sql_update
- F.10. dict_int
- F.11. dict_xsyn
- F.12. dummy_seclabel
- F.13. earthdistance
- F.14. file_fdw
- F.15. fuzzystrmatch
- F.16. hstore
- F.17. intagg
- F.18. intarray
- F.19. isn
- F.20. lo
- F.21. ltree
- F.22. pageinspect
- F.23. passwordcheck
- F.24. pg_buffercache
- F.25. pgcrypto
- F.26. pg_freespacemap
- F.27. pgrowlocks
- F.28. pg_stat_statements
- F.29. pgstattuple
- F.30. pg_trgm
- F.31. postgres_fdw
- F.32. seg
- F.33. sepgsql
- F.34. spi
- F.35. sslinfo
- F.36. tablefunc
- F.37. tcn
- F.38. test_parser
- F.39. tsearch2
- F.40. unaccent
- F.41. uuid-ossp
- F.42. xml2
- Appendix G. 額外提供的程序
- G.1. 客戶端應用程序
- oid2name
- pgbench
- vacuumlo
- G.2. 服務器端應用程序
- pg_archivecleanup
- pg_standby
- pg_test_fsync
- pg_test_timing
- pg_upgrade
- pg_xlogdump
- Appendix H. 外部項目
- H.1. 客戶端接口
- H.2. 管理工具
- H.3. 過程語言
- H.4. 擴展
- Appendix I. 源代碼庫
- I.1. 獲得源代碼通過Git
- Appendix J. 文檔
- J.1. DocBook
- J.2. 工具集
- J.3. 制作文檔
- J.4. 文檔寫作
- J.5. 風格指導
- Appendix K. 首字母縮略詞
- 參考書目
- Index