全部產品
Search
文件中心

:SELECT

更新時間:Jul 06, 2024

本文介紹SELECT相關的查詢語句。

文法

[ WITH with_query [, ...] ]
SELECT [ ALL | DISTINCT ] select_expr [, ...]
[ FROM from_item [, ...] ]
[ WHERE condition ]
[ GROUP BY [ ALL | DISTINCT ] grouping_element [, ...] ]
[ HAVING condition]
[ { UNION | INTERSECT | EXCEPT } [ ALL | DISTINCT ] select ]
[ ORDER BY expression [ ASC | DESC ] [, ...] ]
[ LIMIT [ count | ALL ] ]

參數

  • from_item:有以下兩種形式。
      table_name [ [ AS ] alias [ ( column_alias [, ...] ) ] ]
      from_item join_type from_item [ ON join_condition | USING ( join_column [, ...] ) ]
  • join_type:表的連線類型。
      [ INNER ] JOIN
      LEFT [ OUTER ] JOIN
      RIGHT [ OUTER ] JOIN
      FULL [ OUTER ] JOIN
  • grouping_element
      ()
      expression

WITH從句

WITH從句定義了一個命名好的關係以供在一個查詢裡面使用。 它可以扁平化巢狀查詢或者簡化子查詢。 例如,下面的查詢是等價的。

SELECT a, b
FROM (
  SELECT a, MAX(b) AS b FROM t GROUP BY a
) AS x;

WITH x AS (SELECT a, MAX(b) AS b FROM t GROUP BY a)
SELECT a, b FROM x;

也同樣適用於多子查詢的情況。

WITH
  t1 AS (SELECT a, MAX(b) AS b FROM x GROUP BY a),
  t2 AS (SELECT a, AVG(d) AS d FROM y GROUP BY a)
SELECT t1.*, t2.*
FROM t1
JOIN t2 ON t1.a = t2.a;

另外,在WITH分句中定義的關係可以互相串連。

WITH
  x AS (SELECT a FROM t),
  y AS (SELECT a AS b FROM x),
  z AS (SELECT b AS c FROM y)
SELECT c FROM z;

GROUP BY從句

GROUP BY分句對SELECT語句的輸出進行分組,分組是匹配值的資料行。一個簡單的GROUP BY分句可以包含由輸入列組成的任何錶達式或者或列序號(從1開始)。

以下查詢是等價的。 他們都對nationkey列進行分組, 第一個查詢使用列序號, 第二個查詢使用列名。

SELECT count(*), nationkey FROM customer GROUP BY 2;

SELECT count(*), nationkey FROM customer GROUP BY nationkey;

在查詢語句中沒有指定列名的情況下,GROUP BY子句也可以將輸出進行分組。 例如,以下查詢使用列mktsegment進行分組,統計出customer表的行數。

SELECT count(*) FROM customer GROUP BY mktsegment;
_col0
-------
 29968
 30142
 30189
 29949
 29752
(5 rows)

SELECT語句中使用GROUP BY子句時,所有輸出的列要麼是彙總函式,要麼是GROUP BY子句中的列。

HAVING從句

HAVING子句與彙總函式以及GROUP BY子句共同使用,用來控制選擇分組。HAVING子句去掉不滿足條件的分組。在分組和彙總計算完成後,HAVING對分組進行過濾。以下樣本查詢customer表,並進行分組,查出賬戶餘額大於指定值的記錄。

SELECT count(*), mktsegment, nationkey,
       CAST(sum(acctbal) AS bigint) AS totalbal
FROM customer
GROUP BY mktsegment, nationkey
HAVING sum(acctbal) > 5700000
ORDER BY totalbal DESC;
_col0 | mktsegment | nationkey | totalbal
-------+------------+-----------+----------
  1272 | AUTOMOBILE |        19 |  5856939
  1253 | FURNITURE  |        14 |  5794887
  1248 | FURNITURE  |         9 |  5784628
  1243 | FURNITURE  |        12 |  5757371
  1231 | HOUSEHOLD  |         3 |  5753216
  1251 | MACHINERY  |         2 |  5719140
  1247 | FURNITURE  |         8 |  5701952
(7 rows)

UNION|INTERSECT|EXCEPT從句

UNION、INTERSECT和EXCEPT都是全集合操作符。這些分句被用來組合多於一個查詢語句的結果,最終形成一個結果。

query UNION [ALL | DISTINCT] query

query INTERSECT query

query EXCEPT query

參數ALL或DISTINCT控制最終結果集包含哪些行。如果指定參數ALL,則包含全部行,即使行完全相同。如果指定參數DISTINCT,則合并結果集,結果集只有唯一不重複的行。如果不指定參數,執行時預設使用DISTINCT。

多個集合操作符會從做到有的被處理,除非順序通過括弧被顯示指定。另外,INTERSECT比EXCEPT and UNION有更高的優先順序,意味著A UNION B INTERSECT C EXCEPT D和這個運算式是相同的A UNION (B INTERSECT C) EXCEPT D

UNION

UNION把所有結果集兩個結果集合并起來。下面是一個最簡單的可能使用UNION分句的例子。它選擇了值13並且合并了第二個選擇的值42,把他們結合起來。

SELECT 13
UNION
SELECT 42;
 _col0
-------
    13
    42
(2 rows)

INTERSECT

INTERSECT只返回那些同時在第一個和第二個查詢裡面都出現的行結合。下面的例子是一個最簡單的可能使用INTERSECT分句的例子。它選擇了值13和42並把他們和第二個查詢選擇的值13做合并。既然42值在第一個查詢的結果集中,它並不會被包含在最終的結果集裡面。

SELECT 13
INTERSECT
SELECT 13;
 _col0
-------
    13
(2 rows)

EXCEPT

EXCEPT返回那些行僅存在於第一個查詢結果集不在第二個查詢結果集中。下面是最簡單的使用EXCEPT分句的例子。它選擇了值42並把他們和第二個查詢選擇的值13做合并。既然13也同時存在於第二個查詢結果集中,它不會被包含在最終的結果集中。

SELECT 42
EXCEPT
SELECT 13;
 _col0
-------
   42
(2 rows)

ORDER BY Clause

ORDER BY分句被用來排序一個結果集通過一個或者多個輸出運算式。

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

每個運算式由列名或列序號(從1開始)組成。ORDER BY子句作為查詢的最後一步,在GROUP BYHAVING子句之後。

LIMIT Clause

LIMIT分句限制了最終結果集的行數。LIMIT ALL和略去LIMIT分句的結果一樣。以下樣本為查詢一個大表,LIMIT子句限制它只輸出5行(因為查詢沒有ORDER BY,所以隨意返回幾行)。

SELECT orderdate FROM orders LIMIT 5;

 o_orderdate
-------------
 1996-04-14
 1992-01-15
 1995-02-01
 1995-11-12
 1992-04-26
(5 rows)

Joins

它允許合并來自多個關聯的資料。

交叉串連

SELECT *
FROM nation, region;

nation表包含了25行,region表包含了5行,所以結果兩個表最終產生了125行。

子查詢

一個子查詢是一個包含了查詢的運算式。子查詢當它引用子查詢之外的列時是相關的。邏輯上來說,子查詢會被它的外圍查詢逐行評估。被引用的列將因此是固定的在子查詢的評估過程中。

說明 對於向關聯的子查詢是受限的,並不是每一個形式都是支援的。

EXISTS

EXISTS斷言決定是否一個子查詢可以返回任何行。

SELECT name
FROM nation
WHERE EXISTS (SELECT * FROM region WHERE region.regionkey = nation.regionkey)

IN

IN斷言決定一個子查詢返回的值是否在一個被給定的結果集中。IN的結果依照對nulls的標準結果。子查詢必須產生僅僅一列。

SELECT name
FROM nation
WHERE regionkey IN (SELECT regionkey FROM region)

標量子查詢

標量子查詢是一個非關聯的子查詢,返回零或者1行資料。如果這個子查詢返回了多於一行的資料,那將是個錯誤。如果子查詢沒有返回任何行,則返回的結果是NULL

SELECT name
FROM nation
WHERE regionkey = (SELECT max(regionkey) FROM region)
說明 當前只支援單列可以用在標量子查詢裡。