1. 概述
select-stmt (選擇語句)
隱藏
WITH
RECURSIVE
common-table-expression
,
SELECT
DISTINCT
result-column
,
ALL
FROM
table-or-subquery
join-clause
,
WHERE
expr
GROUP
BY
expr
HAVING
expr
,
WINDOW
window-name
AS
window-defn
,
VALUES
(
expr
)
,
,
compound-operator
select-core
ORDER
BY
LIMIT
expr
ordering-term
,
OFFSET
expr
,
expr
common-table-expression (通用表表達式)
顯示
table-name
(
column-name
)
AS
NOT
MATERIALIZED
(
select-stmt
)
,
compound-operator (複合運算子)
顯示
UNION
UNION
INTERSECT
EXCEPT
ALL
expr (表達式)
顯示
literal-value
bind-parameter
schema-name
.
table-name
.
column-name
unary-operator
expr
expr
binary-operator
expr
function-name
(
function-arguments
)
filter-clause
over-clause
(
expr
)
,
CAST
(
expr
AS
type-name
)
expr
COLLATE
collation-name
expr
NOT
LIKE
GLOB
REGEXP
MATCH
expr
expr
ESCAPE
expr
expr
ISNULL
NOTNULL
NOT
NULL
expr
IS
NOT
DISTINCT
FROM
expr
expr
NOT
BETWEEN
expr
AND
expr
expr
NOT
IN
(
select-stmt
)
expr
,
schema-name
.
table-function
(
expr
)
table-name
,
NOT
EXISTS
(
select-stmt
)
CASE
expr
WHEN
expr
THEN
expr
ELSE
expr
END
raise-function
filter-clause (過濾子句)
顯示
function-arguments (函數參數)
顯示
DISTINCT
expr
,
*
ORDER
BY
ordering-term
,
literal-value (字面值)
顯示
CURRENT_TIMESTAMP
numeric-literal
string-literal
blob-literal
NULL
TRUE
FALSE
CURRENT_TIME
CURRENT_DATE
over-clause (OVER 子句)
顯示
OVER
window-name
(
base-window-name
PARTITION
BY
expr
,
ORDER
BY
ordering-term
,
frame-spec
)
frame-spec (框架規格)
顯示
GROUPS
BETWEEN
UNBOUNDED
PRECEDING
AND
UNBOUNDED
FOLLOWING
RANGE
ROWS
UNBOUNDED
PRECEDING
expr
PRECEDING
CURRENT
ROW
expr
PRECEDING
CURRENT
ROW
expr
FOLLOWING
expr
PRECEDING
CURRENT
ROW
expr
FOLLOWING
EXCLUDE
CURRENT
ROW
EXCLUDE
GROUP
EXCLUDE
TIES
EXCLUDE
NO
OTHERS
raise-function (RAISE 函數)
顯示
RAISE
(
ROLLBACK
,
error-message
)
IGNORE
ABORT
FAIL
type-name (類型名稱)
顯示
join-clause (JOIN 子句)
顯示
ordering-term (排序項)
顯示
expr
COLLATE
collation-name
DESC
ASC
NULLS
FIRST
NULLS
LAST
result-column (結果欄)
顯示
expr
AS
column-alias
*
table-name
.
*
table-or-subquery (表或子查詢)
顯示
schema-name
.
table-name
AS
table-alias
INDEXED
BY
index-name
NOT
INDEXED
table-function-name
(
expr
)
,
AS
table-alias
(
select-stmt
)
(
table-or-subquery
)
,
join-clause
window-defn (視窗定義)
顯示
(
base-window-name
PARTITION
BY
expr
,
ORDER
BY
ordering-term
,
frame-spec
)
frame-spec (框架規格)
顯示
GROUPS
BETWEEN
UNBOUNDED
PRECEDING
AND
UNBOUNDED
FOLLOWING
RANGE
ROWS
UNBOUNDED
PRECEDING
expr
PRECEDING
CURRENT
ROW
expr
PRECEDING
CURRENT
ROW
expr
FOLLOWING
expr
PRECEDING
CURRENT
ROW
expr
FOLLOWING
EXCLUDE
CURRENT
ROW
EXCLUDE
GROUP
EXCLUDE
TIES
EXCLUDE
NO
OTHERS
SELECT 語句用於查詢資料庫。SELECT 的結果是零個或多個資料列,其中每一列都具有固定數量的欄位。SELECT 語句不會對資料庫進行任何更改。
上面的「select-stmt (選擇語句) 」語法圖嘗試在單個圖表中顯示盡可能多的 SELECT 語句語法,因為一些讀者認為這樣很有幫助。以下的「factored-select-stmt (因子化選擇語句) 」是另一種語法圖,表達了相同的語法,但嘗試將語法分解成更小的區塊。
factored-select-stmt (因子化選擇語句)
顯示
WITH
RECURSIVE
common-table-expression
,
select-core
ORDER
BY
LIMIT
expr
compound-operator
ordering-term
,
OFFSET
expr
,
expr
common-table-expression (通用表表達式)
顯示
table-name
(
column-name
)
AS
NOT
MATERIALIZED
(
select-stmt
)
,
select-stmt (選擇語句)
顯示
WITH
RECURSIVE
common-table-expression
,
SELECT
DISTINCT
result-column
,
ALL
FROM
table-or-subquery
join-clause
,
WHERE
expr
GROUP
BY
expr
HAVING
expr
,
WINDOW
window-name
AS
window-defn
,
VALUES
(
expr
)
,
,
compound-operator
select-core
ORDER
BY
LIMIT
expr
ordering-term
,
OFFSET
expr
,
expr
join-clause (JOIN 子句)
顯示
result-column (結果欄)
顯示
expr
AS
column-alias
*
table-name
.
*
table-or-subquery (表或子查詢)
顯示
schema-name
.
table-name
AS
table-alias
INDEXED
BY
index-name
NOT
INDEXED
table-function-name
(
expr
)
,
AS
table-alias
(
select-stmt
)
(
table-or-subquery
)
,
join-clause
window-defn (視窗定義)
顯示
(
base-window-name
PARTITION
BY
expr
,
ORDER
BY
ordering-term
,
frame-spec
)
frame-spec (框架規格)
顯示
GROUPS
BETWEEN
UNBOUNDED
PRECEDING
AND
UNBOUNDED
FOLLOWING
RANGE
ROWS
UNBOUNDED
PRECEDING
expr
PRECEDING
CURRENT
ROW
expr
PRECEDING
CURRENT
ROW
expr
FOLLOWING
expr
PRECEDING
CURRENT
ROW
expr
FOLLOWING
EXCLUDE
CURRENT
ROW
EXCLUDE
GROUP
EXCLUDE
TIES
EXCLUDE
NO
OTHERS
compound-operator (複合運算子)
顯示
UNION
UNION
INTERSECT
EXCEPT
ALL
expr (表達式)
顯示
literal-value
bind-parameter
schema-name
.
table-name
.
column-name
unary-operator
expr
expr
binary-operator
expr
function-name
(
function-arguments
)
filter-clause
over-clause
(
expr
)
,
CAST
(
expr
AS
type-name
)
expr
COLLATE
collation-name
expr
NOT
LIKE
GLOB
REGEXP
MATCH
expr
expr
ESCAPE
expr
expr
ISNULL
NOTNULL
NOT
NULL
expr
IS
NOT
DISTINCT
FROM
expr
expr
NOT
BETWEEN
expr
AND
expr
expr
NOT
IN
(
select-stmt
)
expr
,
schema-name
.
table-function
(
expr
)
table-name
,
NOT
EXISTS
(
select-stmt
)
CASE
expr
WHEN
expr
THEN
expr
ELSE
expr
END
raise-function
filter-clause (過濾子句)
顯示
function-arguments (函數參數)
顯示
DISTINCT
expr
,
*
ORDER
BY
ordering-term
,
literal-value (字面值)
顯示
CURRENT_TIMESTAMP
numeric-literal
string-literal
blob-literal
NULL
TRUE
FALSE
CURRENT_TIME
CURRENT_DATE
over-clause (OVER 子句)
顯示
OVER
window-name
(
base-window-name
PARTITION
BY
expr
,
ORDER
BY
ordering-term
,
frame-spec
)
frame-spec (框架規格)
顯示
GROUPS
BETWEEN
UNBOUNDED
PRECEDING
AND
UNBOUNDED
FOLLOWING
RANGE
ROWS
UNBOUNDED
PRECEDING
expr
PRECEDING
CURRENT
ROW
expr
PRECEDING
CURRENT
ROW
expr
FOLLOWING
expr
PRECEDING
CURRENT
ROW
expr
FOLLOWING
EXCLUDE
CURRENT
ROW
EXCLUDE
GROUP
EXCLUDE
TIES
EXCLUDE
NO
OTHERS
raise-function (RAISE 函數)
顯示
RAISE
(
ROLLBACK
,
error-message
)
IGNORE
ABORT
FAIL
select-stmt (選擇語句)
顯示
WITH
RECURSIVE
common-table-expression
,
SELECT
DISTINCT
result-column
,
ALL
FROM
table-or-subquery
join-clause
,
WHERE
expr
GROUP
BY
expr
HAVING
expr
,
WINDOW
window-name
AS
window-defn
,
VALUES
(
expr
)
,
,
compound-operator
select-core
ORDER
BY
LIMIT
expr
ordering-term
,
OFFSET
expr
,
expr
join-clause (JOIN 子句)
顯示
result-column (結果欄)
顯示
expr
AS
column-alias
*
table-name
.
*
table-or-subquery (表或子查詢)
顯示
schema-name
.
table-name
AS
table-alias
INDEXED
BY
index-name
NOT
INDEXED
table-function-name
(
expr
)
,
AS
table-alias
(
select-stmt
)
(
table-or-subquery
)
,
join-clause
window-defn (視窗定義)
顯示
(
base-window-name
PARTITION
BY
expr
,
ORDER
BY
ordering-term
,
frame-spec
)
frame-spec (框架規格)
顯示
GROUPS
BETWEEN
UNBOUNDED
PRECEDING
AND
UNBOUNDED
FOLLOWING
RANGE
ROWS
UNBOUNDED
PRECEDING
expr
PRECEDING
CURRENT
ROW
expr
PRECEDING
CURRENT
ROW
expr
FOLLOWING
expr
PRECEDING
CURRENT
ROW
expr
FOLLOWING
EXCLUDE
CURRENT
ROW
EXCLUDE
GROUP
EXCLUDE
TIES
EXCLUDE
NO
OTHERS
type-name (類型名稱)
顯示
ordering-term (排序項)
顯示
expr
COLLATE
collation-name
DESC
ASC
NULLS
FIRST
NULLS
LAST
select-core (選擇核心)
顯示
SELECT
DISTINCT
result-column
,
ALL
FROM
table-or-subquery
join-clause
,
WHERE
expr
GROUP
BY
expr
HAVING
expr
,
WINDOW
window-name
AS
window-defn
,
VALUES
(
expr
)
,
,
join-clause (JOIN 子句)
顯示
result-column (結果欄)
顯示
expr
AS
column-alias
*
table-name
.
*
table-or-subquery (表或子查詢)
顯示
schema-name
.
table-name
AS
table-alias
INDEXED
BY
index-name
NOT
INDEXED
table-function-name
(
expr
)
,
AS
table-alias
(
select-stmt
)
(
table-or-subquery
)
,
join-clause
select-stmt (選擇語句)
顯示
WITH
RECURSIVE
common-table-expression
,
SELECT
DISTINCT
result-column
,
ALL
FROM
table-or-subquery
join-clause
,
WHERE
expr
GROUP
BY
expr
HAVING
expr
,
WINDOW
window-name
AS
window-defn
,
VALUES
(
expr
)
,
,
compound-operator
select-core
ORDER
BY
LIMIT
expr
ordering-term
,
OFFSET
expr
,
expr
window-defn (視窗定義)
顯示
(
base-window-name
PARTITION
BY
expr
,
ORDER
BY
ordering-term
,
frame-spec
)
frame-spec (框架規格)
顯示
GROUPS
BETWEEN
UNBOUNDED
PRECEDING
AND
UNBOUNDED
FOLLOWING
RANGE
ROWS
UNBOUNDED
PRECEDING
expr
PRECEDING
CURRENT
ROW
expr
PRECEDING
CURRENT
ROW
expr
FOLLOWING
expr
PRECEDING
CURRENT
ROW
expr
FOLLOWING
EXCLUDE
CURRENT
ROW
EXCLUDE
GROUP
EXCLUDE
TIES
EXCLUDE
NO
OTHERS
請注意,語法圖中存在實際上不允許的路徑。一些例子:
這些以及其他類似的語法限制在正文中進行了描述。
SELECT 語句是 SQL 語言中最複雜的命令。為了使說明更容易理解,以下某些段落將 SELECT 語句返回資料的方式描述為一系列步驟。重要的是要記住,這純粹是說明性的 - 實際上,SQLite 或任何其他 SQL 引擎都不需要遵循此過程或任何其他特定過程。
2. 簡單 SELECT 處理
SELECT 語句的核心是「簡單 SELECT」,由以下的 select-core (選擇核心) 和 simple-select-stmt (簡單選擇語句) 語法圖所示。實際上,大多數 SELECT 語句都是簡單 SELECT 語句。
simple-select-stmt (簡單選擇語句)
隱藏
WITH
RECURSIVE
common-table-expression
,
select-core
ORDER
BY
LIMIT
expr
ordering-term
,
OFFSET
expr
,
expr
common-table-expression (通用表表達式)
顯示
table-name
(
column-name
)
AS
NOT
MATERIALIZED
(
select-stmt
)
,
select-stmt (選擇語句)
顯示
WITH
RECURSIVE
common-table-expression
,
SELECT
DISTINCT
result-column
,
ALL
FROM
table-or-subquery
join-clause
,
WHERE
expr
GROUP
BY
expr
HAVING
expr
,
WINDOW
window-name
AS
window-defn
,
VALUES
(
expr
)
,
,
compound-operator
select-core
ORDER
BY
LIMIT
expr
ordering-term
,
OFFSET
expr
,
expr
compound-operator (複合運算子)
顯示
UNION
UNION
INTERSECT
EXCEPT
ALL
join-clause (JOIN 子句)
顯示
result-column (結果欄)
顯示
expr
AS
column-alias
*
table-name
.
*
table-or-subquery (表或子查詢)
顯示
schema-name
.
table-name
AS
table-alias
INDEXED
BY
index-name
NOT
INDEXED
table-function-name
(
expr
)
,
AS
table-alias
(
select-stmt
)
(
table-or-subquery
)
,
join-clause
window-defn (視窗定義)
顯示
(
base-window-name
PARTITION
BY
expr
,
ORDER
BY
ordering-term
,
frame-spec
)
frame-spec (框架規格)
顯示
GROUPS
BETWEEN
UNBOUNDED
PRECEDING
AND
UNBOUNDED
FOLLOWING
RANGE
ROWS
UNBOUNDED
PRECEDING
expr
PRECEDING
CURRENT
ROW
expr
PRECEDING
CURRENT
ROW
expr
FOLLOWING
expr
PRECEDING
CURRENT
ROW
expr
FOLLOWING
EXCLUDE
CURRENT
ROW
EXCLUDE
GROUP
EXCLUDE
TIES
EXCLUDE
NO
OTHERS
expr (表達式)
顯示
literal-value
bind-parameter
schema-name
.
table-name
.
column-name
unary-operator
expr
expr
binary-operator
expr
function-name
(
function-arguments
)
filter-clause
over-clause
(
expr
)
,
CAST
(
expr
AS
type-name
)
expr
COLLATE
collation-name
expr
NOT
LIKE
GLOB
REGEXP
MATCH
expr
expr
ESCAPE
expr
expr
ISNULL
NOTNULL
NOT
NULL
expr
IS
NOT
DISTINCT
FROM
expr
expr
NOT
BETWEEN
expr
AND
expr
expr
NOT
IN
(
select-stmt
)
expr
,
schema-name
.
table-function
(
expr
)
table-name
,
NOT
EXISTS
(
select-stmt
)
CASE
expr
WHEN
expr
THEN
expr
ELSE
expr
END
raise-function
filter-clause (過濾子句)
顯示
function-arguments (函數參數)
顯示
DISTINCT
expr
,
*
ORDER
BY
ordering-term
,
literal-value (字面值)
顯示
CURRENT_TIMESTAMP
numeric-literal
string-literal
blob-literal
NULL
TRUE
FALSE
CURRENT_TIME
CURRENT_DATE
over-clause (OVER 子句)
顯示
OVER
window-name
(
base-window-name
PARTITION
BY
expr
,
ORDER
BY
ordering-term
,
frame-spec
)
frame-spec (框架規格)
顯示
GROUPS
BETWEEN
UNBOUNDED
PRECEDING
AND
UNBOUNDED
FOLLOWING
RANGE
ROWS
UNBOUNDED
PRECEDING
expr
PRECEDING
CURRENT
ROW
expr
PRECEDING
CURRENT
ROW
expr
FOLLOWING
expr
PRECEDING
CURRENT
ROW
expr
FOLLOWING
EXCLUDE
CURRENT
ROW
EXCLUDE
GROUP
EXCLUDE
TIES
EXCLUDE
NO
OTHERS
raise-function (RAISE 函數)
顯示
RAISE
(
ROLLBACK
,
error-message
)
IGNORE
ABORT
FAIL
select-stmt (選擇語句)
顯示
WITH
RECURSIVE
common-table-expression
,
SELECT
DISTINCT
result-column
,
ALL
FROM
table-or-subquery
join-clause
,
WHERE
expr
GROUP
BY
expr
HAVING
expr
,
WINDOW
window-name
AS
window-defn
,
VALUES
(
expr
)
,
,
compound-operator
select-core
ORDER
BY
LIMIT
expr
ordering-term
,
OFFSET
expr
,
expr
compound-operator (複合運算子)
顯示
UNION
UNION
INTERSECT
EXCEPT
ALL
join-clause (JOIN 子句)
顯示
result-column (結果欄)
顯示
expr
AS
column-alias
*
table-name
.
*
table-or-subquery (表或子查詢)
顯示
schema-name
.
table-name
AS
table-alias
INDEXED
BY
index-name
NOT
INDEXED
table-function-name
(
expr
)
,
AS
table-alias
(
select-stmt
)
(
table-or-subquery
)
,
join-clause
window-defn (視窗定義)
顯示
(
base-window-name
PARTITION
BY
expr
,
ORDER
BY
ordering-term
,
frame-spec
)
frame-spec (框架規格)
顯示
GROUPS
BETWEEN
UNBOUNDED
PRECEDING
AND
UNBOUNDED
FOLLOWING
RANGE
ROWS
UNBOUNDED
PRECEDING
expr
PRECEDING
CURRENT
ROW
expr
PRECEDING
CURRENT
ROW
expr
FOLLOWING
expr
PRECEDING
CURRENT
ROW
expr
FOLLOWING
EXCLUDE
CURRENT
ROW
EXCLUDE
GROUP
EXCLUDE
TIES
EXCLUDE
NO
OTHERS
type-name (類型名稱)
顯示
ordering-term (排序項)
顯示
expr
COLLATE
collation-name
DESC
ASC
NULLS
FIRST
NULLS
LAST
select-core (選擇核心)
隱藏
SELECT
DISTINCT
result-column
,
ALL
FROM
table-or-subquery
join-clause
,
WHERE
expr
GROUP
BY
expr
HAVING
expr
,
WINDOW
window-name
AS
window-defn
,
VALUES
(
expr
)
,
,
join-clause (JOIN 子句)
顯示
result-column (結果欄)
顯示
expr
AS
column-alias
*
table-name
.
*
table-or-subquery (表或子查詢)
顯示
schema-name
.
table-name
AS
table-alias
INDEXED
BY
index-name
NOT
INDEXED
table-function-name
(
expr
)
,
AS
table-alias
(
select-stmt
)
(
table-or-subquery
)
,
join-clause
select-stmt (選擇語句)
顯示
WITH
RECURSIVE
common-table-expression
,
SELECT
DISTINCT
result-column
,
ALL
FROM
table-or-subquery
join-clause
,
WHERE
expr
GROUP
BY
expr
HAVING
expr
,
WINDOW
window-name
AS
window-defn
,
VALUES
(
expr
)
,
,
compound-operator
select-core
ORDER
BY
LIMIT
expr
ordering-term
,
OFFSET
expr
,
expr
compound-operator (複合運算子)
顯示
UNION
UNION
INTERSECT
EXCEPT
ALL
window-defn (視窗定義)
顯示
(
base-window-name
PARTITION
BY
expr
,
ORDER
BY
ordering-term
,
frame-spec
)
frame-spec (框架規格)
顯示
GROUPS
BETWEEN
UNBOUNDED
PRECEDING
AND
UNBOUNDED
FOLLOWING
RANGE
ROWS
UNBOUNDED
PRECEDING
expr
PRECEDING
CURRENT
ROW
expr
PRECEDING
CURRENT
ROW
expr
FOLLOWING
expr
PRECEDING
CURRENT
ROW
expr
FOLLOWING
EXCLUDE
CURRENT
ROW
EXCLUDE
GROUP
EXCLUDE
TIES
EXCLUDE
NO
OTHERS
以下描述中,生成簡單 SELECT 語句的結果呈現為一個四步驟的過程。
FROM 子句 處理:決定簡單 SELECT 的輸入資料。輸入資料若無 FROM 子句則隱含為單列 0 欄,否則由 FROM 子句決定。
WHERE 子句 處理:使用 WHERE 子句表達式過濾輸入資料。
GROUP BY、HAVING 和結果欄表達式 處理:根據任何 GROUP BY 子句彙總資料,並計算過濾後輸入資料集各列的結果集表達式,來計算結果列的集合。
DISTINCT/ALL 關鍵字 處理:如果查詢是「SELECT DISTINCT」查詢,則會從結果列集合中移除重複的列。
簡單 SELECT 語句有兩種類型:聚合查詢和非聚合查詢。如果簡單 SELECT 語句包含 GROUP BY 子句或在結果集中包含一個或多個聚合函數,則它是一個聚合查詢。否則,如果簡單 SELECT 不包含聚合函數或 GROUP BY 子句,則它是非聚合查詢。
簡單 SELECT 查詢使用的輸入資料是一組 N 列,每列 M 欄的資料集。
如果簡單 SELECT 語句省略了 FROM 子句,則輸入資料隱含為單列零欄 (即 N =1 且 M =0)。
如果指定了 FROM 子句,則簡單 SELECT 查詢操作的資料來自 FROM 關鍵字後指定的一個或多個表格或子查詢(括號中的 SELECT 語句)。在簡單 SELECT 語句的 FROM 子句後面的 表格或子查詢 中指定的子查詢,其處理方式如同它是一個包含子查詢語句返回資料的表格。子查詢的每一欄都具有子查詢語句中相應表達式的 定序 和 親和性 。
如果 FROM 子句中只有一個表格或子查詢,則 SELECT 語句使用的輸入資料就是指定表格的內容。如果 FROM 子句中有多個表格或子查詢,則所有表格和/或子查詢的內容會聯結成單個資料集,供簡單 SELECT 語句操作。資料的組合方式取決於用於連接表格或子查詢的特定 聯結運算子 和 聯結約束 。
SQLite 中的所有聯結都基於左右資料集的笛卡爾積。笛卡爾積資料集的欄依序為左資料集的所有欄,後接右資料集的所有欄。笛卡爾積資料集中的一列是由左右資料集中每一行的唯一組合所形成。換句話說,如果左資料集由 N左 列 M左 欄組成,而右資料集由 N右 列 M右 欄組成,則笛卡爾積是一個 N左 ×N右 列的資料集,每列包含 M左 +M右 欄。
如果聯結運算子是「CROSS JOIN」、「INNER JOIN」、「JOIN」或逗號 (「,」),且沒有 ON 或 USING 子句,則聯結的結果就是左右資料集的笛卡爾積。如果聯結運算子確實有 ON 或 USING 子句,則會根據以下要點處理這些子句
如果有 ON 子句,則會針對笛卡爾積的每一列將 ON 表達式作為 布林表達式 進行評估。資料集中只包含表達式評估為 true 的列。
如果存在 USING 子句,則指定的每個欄位名稱都必須同時存在於連接運算符左右兩側的資料集中。對於每一對命名的欄位,表達式「lhs.X = rhs.X」會針對笛卡爾積的每一列作為布林表達式 進行評估。只有所有此類表達式評估為 true 的列才會包含在結果集中。在比較 USING 子句產生的值時,適用於比較中處理親和性、排序序列和 NULL 值的常規規則。出於排序序列和親和性優先順序的目的,連接運算符左側資料集中的欄位被視為比較運算符 (=) 的左側。
對於 USING 子句識別的每一對欄位,來自右側資料集的欄位會從連接的資料集中省略。這是 USING 子句及其等效 ON 限制條件之間的唯一區別。
如果連接運算符中存在 NATURAL 關鍵字,則會將隱式 USING 子句添加到連接限制條件中。隱式 USING 子句包含同時出現在左側和右側輸入資料集中的每個欄位名稱。如果左側和右側輸入資料集沒有共同的欄位名稱,則 NATURAL 關鍵字對連接結果沒有影響。不能將 USING 或 ON 子句添加到指定 NATURAL 關鍵字的連接中。
如果連接運算符是「LEFT JOIN」或「LEFT OUTER JOIN」,則在應用 ON 或 USING 過濾子句後,會為原始左側輸入資料集中與右側資料集中任何列都不匹配的每一列向輸出中添加額外的一列。添加的列在通常包含從右側輸入資料集複製的值的欄位中包含 NULL 值。
如果連接運算符是「RIGHT JOIN」或「RIGHT OUTER JOIN」,則在應用 ON 或 USING 過濾子句後,會為原始右側輸入資料集中與左側資料集中任何列都不匹配的每一列向輸出中添加額外的一列。添加的列在通常包含從左側輸入資料集複製的值的欄位中包含 NULL 值。
「FULL JOIN」或「FULL OUTER JOIN」是「LEFT JOIN」和「RIGHT JOIN」的組合。對於左側資料集中與右側資料集中任何列都不匹配的每一列,以及右側資料集中與左側資料集中任何列都不匹配的每一列,都會添加額外的輸出列。不匹配的欄位會填入 NULL。
當多個表格作為 FROM 子句的一部分連接在一起時,連接操作會從左到右依序處理。換句話說,FROM 子句 (A join-op-1 B join-op-2 C) 的計算方式為 ((A join-op-1 B) join-op-2 C)。
2.2. CROSS JOIN 的特殊處理。
「INNER JOIN」、「JOIN」和「,」連接運算符之間沒有區別。它們在 SQLite 中完全可以互換。「CROSS JOIN」連接運算符產生的結果與「INNER JOIN」、「JOIN」和「,」運算符相同,但在查詢優化器處理 方面有所不同,因為它會阻止查詢優化器重新排序連接中的表格。應用程式開發人員可以使用 CROSS JOIN 運算符直接影響選擇用於實現 SELECT 陳述式的演算法。除非在需要手動控制查詢優化器的特定情況下,否則應避免使用 CROSS JOIN。在應用程式開發的早期應避免使用 CROSS JOIN,因為這樣做是一種過早的優化 。CROSS JOIN 的特殊處理是 SQLite 特有的功能,並不是標準 SQL 的一部分。
2.3. WHERE 子句過濾。
如果指定了 WHERE 子句,則會針對輸入資料中的每一列,將 WHERE 運算式作為布林運算式 進行評估。只有 WHERE 子句運算式評估為 true 的列才會包含在資料集中,然後才會繼續處理。如果 WHERE 子句評估為 false 或 NULL,則會將列從結果中排除。
對於 JOIN 或 INNER JOIN 或 CROSS JOIN,WHERE 子句中的約束運算式和 ON 子句中的約束運算式沒有區別。然而,對於 LEFT 或 RIGHT 或 FULL OUTER JOIN,差異非常重要。在外聯接中,在 ON 子句處理之後但在 WHERE 子句處理之前,會針對另一個運算元上不匹配的列新增額外的 NULL 列。因此,ON 子句中形式為「left.x=right.y」的約束將允許所有新增的 NULL 列通過。但如果相同的約束位於 WHERE 子句中,「right.y」或「left.x」其中一個的 NULL 值將會阻止運算式「left.x=right.y」為 true,從而將該列從輸出中排除。
2.4. 結果列集合的產生
一旦 FROM 子句的輸入資料已被 WHERE 子句運算式(如果有的話)過濾後,就會計算簡單 SELECT 的結果列集合。具體如何執行取決於簡單 SELECT 是聚合查詢還是非聚合查詢,以及是否指定了 GROUP BY 子句。
SELECT 和 FROM 關鍵字之間的運算式清單稱為結果運算式清單。如果結果運算式是特殊運算式「*」,則輸入資料中的所有欄位都會替換該運算式。如果運算式是 FROM 子句中表格或子查詢的別名,後接「.*」,則命名表格或子查詢中的所有欄位都會替換單一運算式。在結果運算式清單以外的任何上下文中使用「*」或「alias.*」運算式都是錯誤的。在沒有 FROM 子句的簡單 SELECT 查詢中使用「*」或「alias.*」運算式也是錯誤的。
簡單 SELECT 陳述式返回的列數等於替換 * 和 alias.* 運算式後結果運算式清單中的運算式數量。每一列結果都是透過針對單列輸入資料評估結果運算式清單中的運算式來計算的,或者對於聚合查詢,則是針對一組列來計算的。
如果 SELECT 陳述式是非聚合查詢 ,則會針對 WHERE 子句過濾的資料集中的每一列評估結果運算式清單中的每個運算式。
如果 SELECT 陳述式是沒有 GROUP BY 子句的聚合查詢 ,則會針對整個資料集評估結果集中每個聚合運算式一次。針對資料集中任意選取的一列評估結果集中每個非聚合運算式一次。每個非聚合運算式都使用相同的任意選取列。或者,如果資料集包含零列,則會針對完全由 NULL 值組成的列評估每個非聚合運算式。
透過評估結果集中聚合和非聚合運算式所建立的單列結果集資料形成了沒有 GROUP BY 子句的聚合查詢的結果。沒有 GROUP BY 子句的聚合查詢始終只返回一列資料,即使輸入資料為零列也是如此。
如果 SELECT 陳述式是一個包含 GROUP BY 子句的聚合查詢 ,那麼 GROUP BY 子句中指定的每個表達式都會根據下方 ORDER BY 表達式的處理規則,針對資料集中的每一列進行評估。然後,每一列會根據結果被分配到一個「群組」;評估 GROUP BY 表達式結果相同的列會被分配到同一個群組。為了將列分組,NULL 值會被視為相等。在評估 GROUP BY 子句中的表達式時,適用於選擇排序序列 的常用規則。GROUP BY 子句中的表達式不 必是結果中出現的表達式。GROUP BY 子句中的表達式不能是聚合表達式。
如果指定了 HAVING 子句,它會針對每一組列作為布林表達式 進行一次評估。如果評估 HAVING 子句的結果為 false,則該群組會被捨棄。如果 HAVING 子句是一個聚合表達式,它會針對群組中的所有列進行評估。如果 HAVING 子句是一個非聚合表達式,它會針對從群組中任意選擇的一列進行評估。HAVING 表達式可以參考結果中沒有的值,甚至是聚合函數。
結果集中每個表達式接著會針對每一組列進行一次評估。如果表達式是一個聚合表達式,它會針對群組中的所有列進行評估。否則,它會針對從群組中任意選擇的單一列進行評估。如果結果集中有多個非聚合表達式,則所有此類表達式都會針對同一列進行評估。
輸入資料集列的每個群組都會貢獻一列到結果列的集合中。根據與 DISTINCT 關鍵字相關聯的篩選,包含 GROUP BY 子句的聚合查詢所返回的列數與將 GROUP BY 和 HAVING 子句應用於已篩選的輸入資料集所產生的列群組數相同。
2.5. 聚合查詢中的裸欄位
通常情況下,聚合查詢中的所有欄位名稱都是聚合函數 的參數,或者出現在 GROUP BY 子句中。包含不在聚合函數內且未出現在 GROUP BY 子句(如果有的話)中的欄位名稱的結果欄位稱為「裸」欄位。範例
SELECT a, b, sum(c) FROM tab1 GROUP BY a;
在上述查詢中,「a」欄位是 GROUP BY 子句的一部分,因此輸出的每一列都包含「a」的不同值之一。「c」欄位包含在 sum() 聚合函數中,因此該輸出欄位是「a」值相同的列中所有「c」值的總和。但是裸欄位「b」的結果是什麼?答案是「b」的結果將是組成聚合的其中一個輸入列中「b」的值。問題是您通常不知道使用哪個輸入列來計算「b」,因此在許多情況下,「b」的值是未定義的。
當聚合函數是 min() 或 max() 時,會進行特殊處理。範例
SELECT a, b, max(c) FROM tab1 GROUP BY a;
如果查詢中只有一個 min() 或 max() 聚合函數,則結果集中所有裸欄位的值都取自也包含最小值或最大值的輸入列。因此在上述查詢中,輸出中「b」欄位的值將是輸入列中「c」值最大的「b」欄位的值。min() 和 max() 的這種特殊行為有一些限制
如果相同的最小值或最大值出現在兩列或多列上,則裸值可能會從這些列中的任何一列中選取。選擇是任意的。無法預測將從哪一列中選擇裸值。對於同一個查詢中的不同裸欄位,選擇可能不同。
如果查詢中存在兩個或多個 min() 或 max() 聚合函數,則單獨的欄位值將取自其中一個聚合函數達到最小值或最大值的行之一。選擇哪個 min() 或 max() 聚合函數來決定單獨欄位值的選取是任意的。在同一個查詢中,不同單獨欄位的選擇可能不同。
這種針對 min() 或 max() 聚合函數的特殊處理僅適用於這些聚合函數的內建實作。如果應用程式使用應用程式定義的替代方案覆蓋內建的 min() 或 max() 聚合函數,則選取的單獨欄位值將取自任意行。
大多數其他 SQL 資料庫引擎不允許單獨的欄位。如果您在查詢中包含單獨的欄位,其他資料庫引擎通常會引發錯誤。在查詢中包含單獨欄位的能力是 SQLite 特有的擴充功能。這被認為是一個特性,而不是錯誤。有關更多資訊,請參閱 SQLite 論壇主題 7481d2a6df8980ff 上的討論。
2.6. 移除重複的行(DISTINCT 處理)
在簡單 SELECT 陳述式中,SELECT 關鍵字後面可以接著 ALL 或 DISTINCT 關鍵字。如果簡單 SELECT 是 SELECT ALL,則 SELECT 會返回完整的結果列集合。如果 ALL 或 DISTINCT 都不存在,則行為如同指定了 ALL。如果簡單 SELECT 是 SELECT DISTINCT,則在返回結果列集合之前,會移除其中的重複行。為了偵測重複行,兩個 NULL 值被視為相等。用於選擇排序序列以比較文字值的一般規則 仍然適用。
3. 複合 SELECT 陳述式
兩個或多個 簡單 SELECT 陳述式可以使用 UNION、UNION ALL、INTERSECT 或 EXCEPT 運算子連接在一起,形成複合 SELECT,如下圖所示
複合選擇陳述式 (compound-select-stmt)
隱藏
WITH
RECURSIVE
common-table-expression
,
select-core
ORDER
BY
LIMIT
expr
UNION
UNION
ALL
select-core
INTERSECT
EXCEPT
ordering-term
,
OFFSET
expr
,
expr
common-table-expression (通用表表達式)
顯示
table-name
(
column-name
)
AS
NOT
MATERIALIZED
(
select-stmt
)
,
select-stmt (選擇語句)
顯示
WITH
RECURSIVE
common-table-expression
,
SELECT
DISTINCT
result-column
,
ALL
FROM
table-or-subquery
join-clause
,
WHERE
expr
GROUP
BY
expr
HAVING
expr
,
WINDOW
window-name
AS
window-defn
,
VALUES
(
expr
)
,
,
compound-operator
select-core
ORDER
BY
LIMIT
expr
ordering-term
,
OFFSET
expr
,
expr
compound-operator (複合運算子)
顯示
UNION
UNION
INTERSECT
EXCEPT
ALL
join-clause (JOIN 子句)
顯示
result-column (結果欄)
顯示
expr
AS
column-alias
*
table-name
.
*
table-or-subquery (表或子查詢)
顯示
schema-name
.
table-name
AS
table-alias
INDEXED
BY
index-name
NOT
INDEXED
table-function-name
(
expr
)
,
AS
table-alias
(
select-stmt
)
(
table-or-subquery
)
,
join-clause
window-defn (視窗定義)
顯示
(
base-window-name
PARTITION
BY
expr
,
ORDER
BY
ordering-term
,
frame-spec
)
frame-spec (框架規格)
顯示
GROUPS
BETWEEN
UNBOUNDED
PRECEDING
AND
UNBOUNDED
FOLLOWING
RANGE
ROWS
UNBOUNDED
PRECEDING
expr
PRECEDING
CURRENT
ROW
expr
PRECEDING
CURRENT
ROW
expr
FOLLOWING
expr
PRECEDING
CURRENT
ROW
expr
FOLLOWING
EXCLUDE
CURRENT
ROW
EXCLUDE
GROUP
EXCLUDE
TIES
EXCLUDE
NO
OTHERS
expr (表達式)
顯示
literal-value
bind-parameter
schema-name
.
table-name
.
column-name
unary-operator
expr
expr
binary-operator
expr
function-name
(
function-arguments
)
filter-clause
over-clause
(
expr
)
,
CAST
(
expr
AS
type-name
)
expr
COLLATE
collation-name
expr
NOT
LIKE
GLOB
REGEXP
MATCH
expr
expr
ESCAPE
expr
expr
ISNULL
NOTNULL
NOT
NULL
expr
IS
NOT
DISTINCT
FROM
expr
expr
NOT
BETWEEN
expr
AND
expr
expr
NOT
IN
(
select-stmt
)
expr
,
schema-name
.
table-function
(
expr
)
table-name
,
NOT
EXISTS
(
select-stmt
)
CASE
expr
WHEN
expr
THEN
expr
ELSE
expr
END
raise-function
filter-clause (過濾子句)
顯示
function-arguments (函數參數)
顯示
DISTINCT
expr
,
*
ORDER
BY
ordering-term
,
literal-value (字面值)
顯示
CURRENT_TIMESTAMP
numeric-literal
string-literal
blob-literal
NULL
TRUE
FALSE
CURRENT_TIME
CURRENT_DATE
over-clause (OVER 子句)
顯示
OVER
window-name
(
base-window-name
PARTITION
BY
expr
,
ORDER
BY
ordering-term
,
frame-spec
)
frame-spec (框架規格)
顯示
GROUPS
BETWEEN
UNBOUNDED
PRECEDING
AND
UNBOUNDED
FOLLOWING
RANGE
ROWS
UNBOUNDED
PRECEDING
expr
PRECEDING
CURRENT
ROW
expr
PRECEDING
CURRENT
ROW
expr
FOLLOWING
expr
PRECEDING
CURRENT
ROW
expr
FOLLOWING
EXCLUDE
CURRENT
ROW
EXCLUDE
GROUP
EXCLUDE
TIES
EXCLUDE
NO
OTHERS
raise-function (RAISE 函數)
顯示
RAISE
(
ROLLBACK
,
error-message
)
IGNORE
ABORT
FAIL
select-stmt (選擇語句)
顯示
WITH
RECURSIVE
common-table-expression
,
SELECT
DISTINCT
result-column
,
ALL
FROM
table-or-subquery
join-clause
,
WHERE
expr
GROUP
BY
expr
HAVING
expr
,
WINDOW
window-name
AS
window-defn
,
VALUES
(
expr
)
,
,
compound-operator
select-core
ORDER
BY
LIMIT
expr
ordering-term
,
OFFSET
expr
,
expr
compound-operator (複合運算子)
顯示
UNION
UNION
INTERSECT
EXCEPT
ALL
join-clause (JOIN 子句)
顯示
result-column (結果欄)
顯示
expr
AS
column-alias
*
table-name
.
*
table-or-subquery (表或子查詢)
顯示
schema-name
.
table-name
AS
table-alias
INDEXED
BY
index-name
NOT
INDEXED
table-function-name
(
expr
)
,
AS
table-alias
(
select-stmt
)
(
table-or-subquery
)
,
join-clause
window-defn (視窗定義)
顯示
(
base-window-name
PARTITION
BY
expr
,
ORDER
BY
ordering-term
,
frame-spec
)
frame-spec (框架規格)
顯示
GROUPS
BETWEEN
UNBOUNDED
PRECEDING
AND
UNBOUNDED
FOLLOWING
RANGE
ROWS
UNBOUNDED
PRECEDING
expr
PRECEDING
CURRENT
ROW
expr
PRECEDING
CURRENT
ROW
expr
FOLLOWING
expr
PRECEDING
CURRENT
ROW
expr
FOLLOWING
EXCLUDE
CURRENT
ROW
EXCLUDE
GROUP
EXCLUDE
TIES
EXCLUDE
NO
OTHERS
type-name (類型名稱)
顯示
ordering-term (排序項)
顯示
expr
COLLATE
collation-name
DESC
ASC
NULLS
FIRST
NULLS
LAST
select-core (選擇核心)
顯示
SELECT
DISTINCT
result-column
,
ALL
FROM
table-or-subquery
join-clause
,
WHERE
expr
GROUP
BY
expr
HAVING
expr
,
WINDOW
window-name
AS
window-defn
,
VALUES
(
expr
)
,
,
join-clause (JOIN 子句)
顯示
result-column (結果欄)
顯示
expr
AS
column-alias
*
table-name
.
*
table-or-subquery (表或子查詢)
顯示
schema-name
.
table-name
AS
table-alias
INDEXED
BY
index-name
NOT
INDEXED
table-function-name
(
expr
)
,
AS
table-alias
(
select-stmt
)
(
table-or-subquery
)
,
join-clause
select-stmt (選擇語句)
顯示
WITH
RECURSIVE
common-table-expression
,
SELECT
DISTINCT
result-column
,
ALL
FROM
table-or-subquery
join-clause
,
WHERE
expr
GROUP
BY
expr
HAVING
expr
,
WINDOW
window-name
AS
window-defn
,
VALUES
(
expr
)
,
,
compound-operator
select-core
ORDER
BY
LIMIT
expr
ordering-term
,
OFFSET
expr
,
expr
compound-operator (複合運算子)
顯示
UNION
UNION
INTERSECT
EXCEPT
ALL
window-defn (視窗定義)
顯示
(
base-window-name
PARTITION
BY
expr
,
ORDER
BY
ordering-term
,
frame-spec
)
frame-spec (框架規格)
顯示
GROUPS
BETWEEN
UNBOUNDED
PRECEDING
AND
UNBOUNDED
FOLLOWING
RANGE
ROWS
UNBOUNDED
PRECEDING
expr
PRECEDING
CURRENT
ROW
expr
PRECEDING
CURRENT
ROW
expr
FOLLOWING
expr
PRECEDING
CURRENT
ROW
expr
FOLLOWING
EXCLUDE
CURRENT
ROW
EXCLUDE
GROUP
EXCLUDE
TIES
EXCLUDE
NO
OTHERS
在複合 SELECT 中,所有組成 SELECT 必須返回相同數量的結果欄位。由於複合 SELECT 的組成部分必須是簡單 SELECT 陳述式,因此它們不能包含 ORDER BY 或 LIMIT 子句。ORDER BY 和 LIMIT 子句只能出現在整個複合 SELECT 的結尾,而且只有在複合 SELECT 的最後一個元素不是 VALUES 子句時才能出現。
使用 UNION ALL 運算子建立的複合 SELECT 會返回 UNION ALL 運算子左側 SELECT 的所有行,以及右側 SELECT 的所有行。UNION 運算子的工作方式與 UNION ALL 相同,只是會從最終結果集中移除重複的行。INTERSECT 運算子返回左側和右側 SELECT 結果的交集。EXCEPT 運算子返回左側 SELECT 返回的行中,未在右側 SELECT 中返回的子集。在返回結果集之前,會從 INTERSECT 和 EXCEPT 運算子的結果中移除重複的行。
在判斷複合 SELECT 運算子結果的重複列時,NULL 值被視為與其他 NULL 值相等,但與所有非 NULL 值不同。用於比較兩個文字值的排序序列,如同將左右 SELECT 陳述式的欄位分別視為等於 (=) 運算子的左右運算元一樣來決定,但不會優先採用以 COLLATE 運算子後綴指定的排序序列。在比較列作為複合 SELECT 的一部分時,不會對任何值套用親和力轉換。
當三個或更多個簡單 SELECT 連接成一個複合 SELECT 時,它們會從左到右分組。換句話說,如果「A」、「B」和「C」都是簡單 SELECT 陳述式,則 (A op B op C) 會被處理為 ((A op B) op C)。
4. ORDER BY 子句
如果傳回多個列的 SELECT 陳述式沒有 ORDER BY 子句,則傳回列的順序未定義。或者,如果 SELECT 陳述式具有 ORDER BY 子句,則附加到 ORDER BY 的表達式列表決定了傳回給使用者的列的順序。
在複合 SELECT 陳述式中,只有最後一個或最右邊的簡單 SELECT 可以有 ORDER BY 子句。該 ORDER BY 子句將套用於複合式的所有元素。如果複合 SELECT 的最右邊元素是VALUES 子句,則該陳述式不允許使用 ORDER BY 子句。
首先根據 ORDER BY 列表中最左邊表達式的計算結果對列進行排序,然後透過計算第二個最左邊的表達式來打破平局,依此類推。所有 ORDER BY 表達式計算結果都相等的兩列的傳回順序未定義。每個 ORDER BY 表達式後面可以選擇性地接著關鍵字 ASC(較小的值先傳回)或 DESC(較大的值先傳回)。如果未指定 ASC 或 DESC,則預設情況下以升序(較小的值優先)排序列。
基於排序目的,SQLite 將 NULL 值視為小於任何其他值。因此,NULL 自然會出現在 ASC 排序的開頭和 DESC 排序的結尾。可以使用「ASC NULLS LAST」或「DESC NULLS FIRST」語法來更改此行為。
每個 ORDER BY 表達式都按以下方式處理:
如果 ORDER BY 表達式是常數整數 K,則該表達式被視為結果集中第 K 個欄位的別名(欄位從左到右編號,從 1 開始)。
如果 ORDER BY 表達式是一個與其中一個輸出欄位的別名相對應的識別碼,則該表達式被視為該欄位的別名。
否則,如果 ORDER BY 表達式是任何其他表達式,則會對其進行計算,並使用傳回的值對輸出列進行排序。如果 SELECT 陳述式是一個簡單 SELECT,則 ORDER BY 可以包含任何任意表達式。但是,如果 SELECT 是一個複合 SELECT,則不是輸出欄位別名的 ORDER BY 表達式必須與用作輸出欄位的表達式完全相同。
為了排序列,值的比較方式與比較表達式 相同。用於比較兩個文字值的排序序列按以下方式確定:
如果使用後綴COLLATE 運算子 為 ORDER BY 表達式指定了排序序列,則使用指定的排序序列。
否則,如果 ORDER BY 表達式是已使用後綴COLLATE 運算子 指定排序序列的表達式的別名,則使用指定給別名表達式的排序序列。
否則,如果 ORDER BY 表達式是一個欄位或一個表達式的別名(該表達式是一個欄位),則使用該欄位的預設排序序列。
否則,將使用 BINARY 排序序列。
在 複合 SELECT 語句中,所有 ORDER BY 運算式都被視為複合結果欄位之一的別名。如果 ORDER BY 運算式不是整數別名,則 SQLite 會在複合語句中最左邊的 SELECT 中搜尋符合上述第二或第三條規則的結果欄位。如果找到相符的欄位,則搜尋停止,並且該運算式將被視為與其相符的結果欄位的別名。否則,將嘗試下一個靠右的 SELECT,依此類推。如果在任何組成 SELECT 的結果欄位中都找不到相符的運算式,則會發生錯誤。ORDER BY 子句的每個項會分別處理,並且可以與複合語句中不同 SELECT 語句的結果欄位相符。
5. LIMIT 子句
LIMIT 子句用於設定整個 SELECT 語句所返回列數的上限。
在 複合 SELECT 中,只有最後一個或最右邊的 簡單 SELECT 可以包含 LIMIT 子句。在 複合 SELECT 中,LIMIT 子句適用於整個複合語句,而不僅僅是最後一個 SELECT。如果最右邊的 簡單 SELECT 是 VALUES 子句 ,則不允許使用 LIMIT 子句。
任何純量運算式都可以在 LIMIT 子句中使用,只要它計算結果為整數或可以無損轉換為整數的值。如果運算式計算結果為 NULL 值或任何其他無法無損轉換為整數的值,則會返回錯誤。如果 LIMIT 運算式計算結果為負值,則返回的列數沒有上限。否則,SELECT 只返回其結果集的前 N 列,其中 N 是 LIMIT 運算式計算結果的值。或者,如果沒有 LIMIT 子句,SELECT 語句將返回少於 N 列,則返回整個結果集。
附加在 LIMIT 子句之後的選用 OFFSET 子句中的運算式也必須計算結果為整數,或可以無損轉換為整數的值。如果運算式具有 OFFSET 子句,則 SELECT 語句返回的結果集中會省略前 M 列,並返回接下來的 N 列,其中 M 和 N 分別是 OFFSET 和 LIMIT 子句計算結果的值。或者,如果沒有 LIMIT 子句,SELECT 將返回少於 M+N 列,則會跳過前 M 列並返回剩餘的列(如果有的話)。如果 OFFSET 子句計算結果為負值,則結果與其計算結果為零時相同。
LIMIT 子句可以指定兩個以逗號分隔的純量運算式,而不是單獨的 OFFSET 子句。在這種情況下,第一個運算式用作 OFFSET 運算式,第二個運算式用作 LIMIT 運算式。這與使用 OFFSET 子句時,兩個運算式中第二個是 OFFSET,第一個是 LIMIT 的情況相反,這有點違背直覺。這種偏移量和限制的反轉是有意的,它最大限度地提高了與其他 SQL 資料庫系統的相容性。但是,為了避免混淆,強烈建議程式設計師使用帶有「OFFSET」關鍵字的 LIMIT 子句形式,並避免使用帶有逗號分隔偏移量的 LIMIT 子句。
6. VALUES 子句
片語「VALUES(expr-list )」的含義與「SELECT expr-list 」相同。片語「VALUES(expr-list-1 ),...,(expr-list-N )」的含義與「SELECT expr-list-1 UNION ALL ... UNION ALL SELECT expr-list-N 」相同。兩種形式相同,不同之處在於複合語句中 SELECT 語句的數量受 SQLITE_LIMIT_COMPOUND_SELECT 的限制,而 VALUES 子句中的列數沒有任意限制。
VALUES 子句的使用有一些限制,這些限制在語法圖中並未顯示。
7. WITH 子句
SELECT 陳述式前面可以選擇性地加上一個 WITH 子句 ,該子句定義一個或多個 通用表表達式 (CTE),供 SELECT 陳述式內部使用。
8. FROM 子句中的表值函式
包含 隱藏欄位 的 虛擬表 可以在 FROM 子句中像 表值函式 一樣使用。表值函式的參數會成為虛擬表隱藏欄位的限制條件。更多資訊可以在 虛擬表文件 中找到。
9. 與標準 SQL 的差異
SQLite 的 SELECT 語法與標準 SQL 略有不同。這些差異是由於幾個原因造成的:
在 2000 年代中期,非常強調保持函式庫的體積盡可能小,以免在記憶體有限的摺疊式手機等裝置上佔用太多空間。
在 SQLite 的早期,主要開發人員試圖遵循 波斯特爾法則 (Postel's Law),並對接受的輸入保持寬容和彈性。
早期 SQLite 解析器中存在錯誤,會接受一些奇怪的輸入。
主要開發人員對 SQL 的理解並不完美。
無論輸入怪癖的來源為何,我們通常避免嘗試「修復」它們,因為對輸入語法施加任何新的限制都可能導致至少數百萬個使用 SQLite 的應用程式損壞。我們不希望這樣。SQLite 開發團隊的目標是盡可能地保持向下相容性。因此,如果語法怪癖是無害的,我們會保留它並在此處記錄,而不是嘗試修復它。
9.1. 奇怪的 JOIN 名稱
SQLite 接受所有常用的 JOIN 運算子語法:
join-operator (JOIN 運算子)
隱藏
NATURAL
LEFT
OUTER
JOIN
,
RIGHT
FULL
INNER
CROSS
但它不僅如此。SQLite 實際上在指定 JOIN 運算子的方式上非常靈活。一般的語法是:
blah blah blah JOIN
其中有 1 到 3 個「blah 」的實例,每個實例可以是「CROSS」、「FULL」、「INNER」、「LEFT」、「NATURAL」、「OUTER」或「RIGHT」。SQLite 解析器將這些關鍵字中的每一個都視為 JOIN 的屬性,可以按任意順序組合。這就產生了許多超出語法圖規範的新的、有創意的 JOIN 類型。其中一些非標準的 JOIN 類型是被明確禁止的。例如,您不能說「INNER OUTER JOIN」,因為這是矛盾的。但是您可以說「OUTER LEFT NATURAL JOIN」,這與「NATURAL LEFT OUTER JOIN」的意義相同。或者您可以說「LEFT RIGHT JOIN」,這與「FULL JOIN」的意義相同。
請記住:您可以 使用這些非標準的 JOIN 類型,但您不應該 這樣做。為了與其他 SQL 資料庫引擎的相容性,請堅持使用標準的 JOIN 語法。
9.2. 靈活的 JOIN 語法
標準 SQL 對 JOIN 語法的限制比 SQLite 更嚴格。在標準 SQL 中,除了逗號 JOIN、CROSS JOIN 和 NATURAL JOIN 之外,所有 JOIN 都必須具有 ON 子句或 USING 子句,而逗號 JOIN、CROSS JOIN 和 NATURAL JOIN 則不得具有 ON 或 USING 子句。SQLite 對 JOIN 語法沒有那麼嚴格。SQLite 會接受並處理逗號 JOIN 或 CROSS JOIN 上的 ON 或 USING 子句,並且允許您從任何 JOIN 中省略 ON 或 USING 子句。在 SQLite 中,唯一的限制是:
SQLite 甚至允許您從外部 JOIN 中省略 ON 或 USING 子句,儘管這樣做意味著外部 JOIN 是不受限制的(如同 ON 子句是「ON true(開啟) ),這會使外連接的行為類似於內連接。
9.3. 逗號連接和 CROSS JOIN 的優先順序
在標準 SQL 中,使用 JOIN 關鍵字的連接優先於逗號連接。也就是說,JOIN 運算符會在逗號運算符之前執行。SQLite 並非如此,在 SQLite 中所有連接的優先順序都相同。
考慮以下範例
... FROM t1, t2 NATURAL FULL JOIN t3 ...
在標準 SQL 中,t2 和 t3 之間的 FULL JOIN 會先執行,然後左連接的結果會與 t1 交叉連接。但 SQLite 總是從左到右處理所有連接。因此,SQLite 會先對 t1 和 t2 執行交叉連接,然後該交叉連接的結果會饋送到與 t3 的 FULL JOIN。內連接本質上是結合性的,因此只有當您的 FROM 子句包含一個或多個外連接時,差異才會顯現。
您可以透過遵循以下風格規則來解決此問題,並使您的 SQL 陳述式在所有系統之間可攜:
這些建議中的任何一條都足以避免問題,而且大多數程式設計師會本能地遵循所有這些建議,而無需被告知,因此 SQLite 中逗號連接和 JOIN 關鍵字之間缺乏優先順序差異的情況在實務中很少出現。但您應該注意這個問題,以防它真的出現。
此頁面最後修改時間:2024-05-11 12:18:17 UTC