| PostgreSQL 8.0.0 中文文件(轉譯自 PostgreSQL 中國 製作的簡體中文版本) | ||||
|---|---|---|---|---|
| Prev | Fast Backward | Chapter 7. 查詢 | Fast Forward | Next |
如前面的小節說明的那樣, 在 SELECT 命令裡的資料表資料表達式構造了一個中介性的虛擬資料表, 方法可能有組合資料表,視圖,刪除行,分組等等。 這個資料表最後傳遞給選擇列資料表處理。 選擇列資料表判斷中間資料表的哪個字串最終實際輸出。
最簡單的選擇列資料表類型是 *,它發出資料表資料表達式生成的所有字串。 否則,一個選擇列資料表是一個逗號分隔的值資料表達式的列資料表, (和在Section 4.2 裡定義的一樣)。 比如,它可能是一個字串名字的列資料表:
SELECT a, b, c FROM ...
字串名字a,b,和c要麼是在 FROM子句裡引用的資料表中字串的實際名字, 要麼是象 Section 7.2.1.2 裡解釋的那樣的別名。 在選擇列資料表裡的名字空間和在 WHERE 子句裡的名字空間是一樣的, 除非您使用了分組,這時候它和HAVING子句一樣。
如果超過一個資料表有同樣的字串名字,那麼您還必須給出資料表名字,像
SELECT tbl1.a, tbl2.a, tbl1.b FROM ...
(又見 Section 7.2.2)。
如果將任意值資料表達式用於選擇列資料表,那麼它在概念上向返回的資料表中增加了一個新的虛擬字串。 值資料表達式為結果的每一行進行一次計算,計算之前用該行的數值代換任何資料表達式裡引用的字串。 不過選擇列資料表中的這個資料表達式並非一定要引用來自FROM子句中資料表資料表達式裡面的字串, 比如,它也可以是任意常量算術資料表達式。
選擇列資料表中的記錄可以賦予名字,用於進一步的處理。 這裡的"進一步處理"是一個可選的排序聲明和客戶端應用(比如,用於顯示的字串頭)。比如:
SELECT a AS value, b + c AS sum FROM ...
如果沒有使用AS聲明字串名字,那麼系統賦予一個預設值。對於簡單的字串引用, 它是該字串的名字。對於函數調用,它是函數的名字。對於複雜資料表達式,系統會生成一個通用的名字。
注意: 輸出字串的命名和在FROM子句裡的命名是不一樣的 (參閱 Section 7.2.1.2)。 這個管道實際上允許您對同一個列命名兩次,但是在選擇列資料表中選擇的名字是要傳遞的名字。
在處理完選擇列資料表之後,生成的資料表可以刪除重複行。 我們可以直接在 SELECT 後面寫上 DISTINCT 關鍵字聲明:
SELECT DISTINCT select_list ...
(如果不用 DISTINCT 您可以用 ALL 聲明保留所有行的預設行為。)
顯然,如果兩行裡至少有一個列有不同的值,那麼我們認為它是獨立的。空值在這種考慮中認為是相同的。
另外,我們還可以用任意資料表達式來判斷什麼行可以認為是獨立的:
SELECT DISTINCT ON (expression [, expression ...]) select_list ...這裡 expression 是任意值資料表達式, 它為所有行計算。如果一個行集合裡所有行計算出的該資料表達式的值是一樣的, 那麼我們認為它們是重複的並且因此只有第一行保留在輸出中。 請注意這裡的一個集合的"第一行"是不可預料的, 除非您在足夠多的字串上對該查詢排了序,保證到達DISTINCT過濾器的行的順序是唯一的。 (DISTINCT ON處理是發生在ORDER BY排序後面的。)
DISTINCT ON子句不是 SQL 標準的一部分, 有時候有人認為它是一個糟糕的風格,因為它的結果是不可判定的。 如果用有選擇的GROUP BY和在FROM中的子查詢,那麼我們可以避免使用這個構造, 但是通常它是更方便的候選方法。