行.
INTERSECT 的结果不包含任何重复行,除非你声明了 ALL 选项. 用了 ALL 以后,一个在 L 里有 m 个重复而在 R 里有 n 个重复 的行将出现 min(m,n) 次.
除非用圆括号指明顺序, 同一 SELECT 语句中的多个 INTERSECT 操作符是从左向右计算的。 INTERSECT 比 UNION 绑定得更紧 --- 也就是说 A UNION B INTERSECT C 将读做 A UNION (B INTERSECT C),除非你用圆括弧声明.
EXCEPT 子句
table_query EXCEPT [ ALL ] table_query
[ ORDER BY expression [ ASC | DESC | USING operator ] [, ...] ]
[ LIMIT { count | ALL } ]
[ OFFSET start ]
这里 table_query 声明任何没有 ORDER BY,FOR UPDATE,或者 LIMIT 子句的选择表达式。
EXCEPT 类似于 UNION,只不过 EXCEPT 给出存在于左边查询输出而不存在于右边查询输出的行。
EXCEPT 的结果不包含任何重复的行,除非声明了 ALL 选项. 使用ALL时,一个在 L 中有 m 个重复而在 R 中有 n 个重复的行 将出现 max(m-n,0) 次.
除非用圆括弧指明顺序, 同一 SELECT 语句中的多个 EXCEPT 操作符是从左向右计算的。 EXCEPT 和 UNION 绑定级别相同.
LIMIT 子句
LIMIT { count | ALL }
OFFSET start
这里 count 声明返回的最大行数,而 start 声明开始返回行之前忽略的行数。
LIMIT 允许你检索由查询其他部分生成的行的某一部分。 如果给出了限制计数,那么返回的行数不会超过哪个限制。 如果给出了一个偏移量,那么开始返回行之前会忽略那个数量的行。
在使用 LIMIT 时, 一个好习惯是使用一个 ORDER BY 子句把结果行限制成一个唯一的顺序。 否则你会得到无法预料的查询返回的子集 --- 你可能想要第十行到第二十行, 但以什么顺序?除非你声明 ORDER BY,否则你不知道什么顺序。
从 PostgreSQL 7.0 开始, 查询优化器在生成查询规划时把 LIMIT 考虑进去了, 所以你很有可能因给出的 LIMIT 和 OFFSET 值不同而得到不同的 规划(生成不同的行序)。 因此用不同的 LIMIT/OFFSET 值选择不同的查询结果的子集 将不会产生一致的结果, 除非你用 ORDER BY 强制生成一个可预计的结果顺序。 这可不是毛病;这是 SQL 生来的特点,因为除非用了 ORDER BYE 约束顺序, SQL 不保证查询生成的结果有任何特定的顺序。
用法
将表 films 和表 distributors 连接在一起:
SELECT f.title, f.did, d.name, f.date_prod, f.kind
FROM distributors d, films f
WHERE f.did = d.did
title | did | name | date_prod | kind
---------------------------+-----+------------------+------------+----------
The Third Man | 101 | British Lion | 1949-12-23 | Drama
The African Queen | 101 | British Lion | 1951-08-11 | Romantic
Une Femme est une Femme | 102 | Jean Luc Godard | 1961-03-12 | Romantic
Vertigo | 103 | Paramount | 1958-11-14 | Action
Becket | 103 | Paramount | 1964-02-03 | Drama
48 Hrs | 103 | Paramount | 1982-10-22 | Action
War and Peace | 104 | Mosfilm | 1967-02-12 | Drama
West Side Story | 105 | United Artists | 1961-01-03 | Musical
Bananas | 105 | United Artists | 1971-07-13 | Comedy
Yojimbo | 106 | Toho | 1961-06-16 | Drama
There's a Girl in my Soup | 107 | Columbia | 1970-06-11 | Comedy
Taxi Driver | 107 | Columbia | 1975-05-15 | Action
Absence of Malice | 107 | Columbia | 1981-11-15 | Action
Storia di una donna | 108 | Westward | 1970-08-15 | Romantic
The King and I | 109 | 20th Century Fox | 1956-08-11 | Musical
Das Boot | 110 | Bavaria Atelier | 1981-11-11 | Drama
Bed Knobs and Broomsticks | 111 | Walt Disney | | Musical
(17 rows)
统计用kind 分组的所有电影和组的列/字段的 len(长度)的和:
SELECT kind, SUM(len) AS total FROM films GROUP BY kind;
kind | total
----------+-------
Action | 07:34
Comedy | 02:58
Drama | 14:28
Musical | 06:42
Romantic | 04:38
(5 rows)
统计所有电影(films),组的列/字段 len(长度)的和,用 kind 分组并且显示小于5小时的组总和:
SELECT kind, SUM(len) AS total
FROM films
GROUP BY kind
HAVING SUM(len) < INTERVAL '5 hour';
kind | total
----------+-------
Comedy | 02:58
Romantic | 04:38
(2 rows)
下面两个例子是根据第二列 (name)的内容对单独的结果排序的经典的方法:
SELECT * FROM distributors ORDER BY name;
SELECT * FROM distributors ORDER BY 2;
did | name
-----+------------------
109 | 20th Century Fox
110 | Bavaria Atelier
101 | British Lion
107 | Columbia
102 | Jean Luc Godard
113 | Luso films
104 | Mosfilm
103 | Paramount
106 | Toho
105 | United Artists
111 | Walt Disney
112 | Warner Bros.
108 | Westward
(13 rows)
这个例子演示如何获得表 distributors 和 actors的连接, 只将每个表中以字母 W 开头的取出来. 因为只取了不相关的行,所以关键字 ALL 被省略了:
distributors: actors:
did | name id | name
-----+-------------- ----+----------------
108 | Westward 1 | Woody Allen
111 | Walt Disney 2 | Warren Beatty
112 | Warn