SQL 里面最常用的命令是 SELECT 语句,用于检索数据。语法是: SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ]
* | expression [ AS output_name ] [, ...]
[ INTO [ TEMPORARY | TEMP ] [ TABLE ] new_table ]
[ FROM from_item [, ...] ]
[ WHERE condition ]
[ GROUP BY expression [, ...] ]
[ HAVING condition [, ...] ]
[ { UNION | INTERSECT | EXCEPT [ ALL ] } select ]
[ ORDER BY expression [ ASC | DESC | USING operator ] [, ...] ]
[ FOR UPDATE [ OF class_name [, ...] ] ]
[ LIMIT { count | ALL } [ { OFFSET | , } start ]]
现在我们将通过不同的例子演示 SELECT 语句复杂的语法。用于这些例子的表在 供应商和部件数据库 里定义。 1.4.1.1. 简单的 Select这里是一些使用 SELECT 语句的简单例子: Example 1-4. 带有条件的简单查询 要从表 PART 里面把字段 PRICE 大于 10 的所有记录找出来, 我们写出下面查询: SELECT * FROM PART
WHERE PRICE > 10;
然后得到表: PNO | PNAME | PRICE
-----+---------+--------
3 | Bolt | 15
4 | Cam | 25
在 SELECT语句里使用 "*" 将检索出表中的所有属性。 如果我们只希望从表 PART 中检索出属性 PNAME 和 PRICE, 我们使用下面的语句: SELECT PNAME, PRICE
FROM PART
WHERE PRICE > 10;
这回我们的结果是: PNAME | PRICE
--------+--------
Bolt | 15
Cam | 25
请注意 SQL 的 SELECT 语句对应关系演算里面的 "projection" (映射),而不是 "selection"(选择)(参阅 关系演算 获取详细信息)。 WHERE 子句里的条件也可以用关键字 OR,AND,和 NOT 逻辑地连接起来: SELECT PNAME, PRICE
FROM PART
WHERE PNAME = ''''Bolt'''' AND
(PRICE = 0 OR PRICE <= 15);
这样将生成下面的结果: PNAME | PRICE
--------+--------
Bolt | 15
目标列表和 WHERE 子句里可以使用算术操作。例如, 如果我们想知道如果我们买两个部件的话要多少钱, 我们可以用下面的查询: SELECT PNAME, PRICE * 2 AS DOUBLE
FROM PART
WHERE PRICE * 2 < 50;
这样我们得到: PNAME | DOUBLE
--------+---------
Screw | 20
Nut | 16
Bolt | 30
请注意在关键字 AS 后面的 DOUBLE 是第二个列的新名字。 这个技巧可以用于目标列表里的每个元素, 给它们赋予一个在结果列中显示的新的标题。 这个新的标题通常称为别名。这个别名不能在该查询的其他地方使用。 1.4.1.2. Joins(连接)下面的例子显示了 SQL 里是如何实现连接的。 要在共同的属性上连接三个表 SUPPLIER,PART 和 SELLS, 我们通常使用下面的语句: SELECT S.SNAME, P.PNAME
FROM SUPPLIER S, PART P, SELLS SE
WHERE S.SNO = SE.SNO AND
P.PNO = SE.PNO;
而我们得到的结果是: SNAME | PNAME
-------+-------
Smith | Screw
Smith | Nut
Jones | Cam
Adams | Screw
Adams | Bolt
Blake | Nut
Blake | Bolt
Blake | Cam
在 FROM 子句里,我们为每个关系使用了一个别名, 因为在这些关系间有着公共的命名属性(SNO 和 PNO)。 现在我们可以区分不同表的公共命名属性, 只需要简单的用每个关系的别名加上个点做前缀就行了。 联合是用与 一个内部联接 里显示的同样的方法计算的。首先算出笛卡儿积 SUPPLIER × PART × SELLS 。然后选出那些满足 WHERE 子句里给出的条件的记录 (也就是说,公共命名属性的值必须相等)。 最后我们映射出除 S.SNAME 和 P.PNAME 外的所有属性。 另外一个进行连接的方法是使用下面这样的 SQL JOIN 语法: select sname, pname from supplier
JOIN sells USING (sno)
JOIN part USING (pno);
giving again: sname | pname
-------+-------
Smith | Screw
Adams | Screw
Smith | Nut
Blake | Nut
Adams | Bolt
Blake | Bolt
Jones | Cam
Blake | Cam
(8 rows)
一个用 JOIN 语法创建的连接表,是一个出现在 FROM 子句里的, 在任何 WHERE,GROUP BY 或 HAVING 子句之前的表引用列表项. 其它表引用,包括表名字或者其它 JOIN 子句,如果用逗号分隔的话, 可以包含在 FROM 子句里. 连接生成的表逻辑上和任何其它在 FROM 子句里列出的表都一样. SQL JOIN 有两种主要类型,CROSS JOIN (无条件连接) 和条件连接.条件连接还可以根据声明的 连接条件(ON,USING,或 NATURAL)和它 应用的方式(INNER 或 OUTER 连接)进一步细分. 连接类型 - CROSS JOIN
{ T1 } CROSS JOIN { T2 } 一个交叉连接(cross join)接收两个分别有 N 行和 M 行 的表 T1 和 T2,然后返回一个包含交叉乘积 NxM 条记录的 连接表. 对于 T1 的每行 R1,T2 的每行 R2 都与 R1 连接生成 连接的表行 JR,JR 包含所有 R1 和 R2 的字段. CROSS JOIN 实际上就是一个 INNER JOIN ON TRUE. - 条件 JOIN
{ T1 } [ NATURAL ] [ INNER | { LEFT | RIGHT | FULL } [ OUTER ] ] JOIN { T2 } { ON search condition | USING ( join column list ) } 一个条件 JOIN 必须通过提供一个(并且只能有一个) NATURAL,ON,或者 USING 这样的关键字来声明它的 连接条件. ON 子句 接受一个 search condition, 它与一个 WHERE 子句相同.USING 子句接受一个用逗号分隔的 字段名列表,连接表中必须都有这些字段, 并且用那些字段连接这些表,生成的连接表包含每个共有字段 和两个表的所有其它字段. NATURAL 是 USING 子句的缩写,它列出两个表中所有公共 的字段名字.使用 USING 和 NATURAL 的副作用是 每个连接的字段都只有一份拷贝出现在结果表中 (与前面定义的关系演算的 JOIN 相比较). [ INNER ] JOIN 对于 T1 的每行 R1,连接成的表在 T2 里都有一行满 足与 R1 一起的连接条件. 对于所有 JOIN 而言,INNER 和 OUTER 都是可选的.INNER 是缺省. LEFT,RIGHT,和 FULL 只用于 OUTER JOIN. LEFT [ OUTER ] JOIN 首先,执行一次 INNER JOIN. 然后,如果 T1 里有一行对任何 T2 的行都不满足 连接条件,那么返回一个连接行,该行的 T2 的字段 为 null. IP">小技巧: 连接成的表无条件地包含 T1 里的所有行. RIGHT [ OUTER ] JOIN 首先,执行一次 INNER JOIN. 然后,如果 T2 里有一行对任何 T1 的行都不满足 连接条件,那么返回一个连接行,该行的 T1 的字段 为 null. IP">小技巧: 连接成的表无条件地包含 T2 里的所有行. FULL [ OUTER ] JOIN 首先,执行一次 INNER JOIN. 然后,如果 T1 里有一行对任何 T2 的行都不满足 连接条件,那么返回一个连接行,该行的 T1 的字段 为 null. 同样,如果 T2 里有一行对任何 T1 的行都不满足 连接条件,那么返回一个连接行,该行的 T2 的字段 为 null. 小技巧: 连接成的表无条件地拥有来自 T1 的每 一行和来自 T2 的每一行.
所有 类型的 JOIN 都可以链接在一起或者嵌套在一起, 这时 T1 和 T2 都可以是连接生成的表.我们可以使用圆括弧控制 JOIN 的顺序,如果我们不主动控制,那么连接顺序是从左到右. 1.4.1.3. 聚集操作符SQL 提供以一些聚集操作符(如, AVG,COUNT,SUM,MIN,MAX),这些聚集操作符以一个表达式为参数。 只要是满足 WHERE 子句的行,就会计算这个表达式, 然后聚集操作符对这个输入数值的集合进行计算. 通常,一个聚集对整个 SELECT 语句计算的结果是 生成一个结果.但如果在一个查询里面声明了分组, 那么数据库将对每个组进行一次独立的计算,并且 聚集结果是按照各个组出现的(见下节). Example 1-5. 聚集 果我们想知道表 PART 里面所有部件的平均价格,我们可以使用下面查询: SELECT AVG(PRICE) AS AVG_PRICE
FROM PART;
结果是: AVG_PRICE
-----------
14.5
如果我们想知道在表 PART 里面存储了多少部件,我们可以使用语句: SELECT COUNT(PNO)
FROM PART;
得到: COUNT
-------
4
1.4.1.4. 分组聚集SQL 允许我们把一个表里面的记录分成组。 然后上面描述的聚集操作符可以应用于这些组上 (也就是说,聚集操作符的值不再是对所有声明的列的值进行操作, 而是对一个组的所有值进行操作。这样聚集函数是为每个组独立地进行计算的。) 对记录的分组是通过关键字 GROUP BY 实现的,GROUP BY 后面跟着一个定义组的构成的属性列表。 如果我们使用语句 GROUP BY A1, ⃛, Ak 我们就把关系分成了组,这样当且仅当两条记录在所有属性 A1, ⃛, Ak 上达成一致,它们才是同一组的。 Example 1-6. 聚集 如果我们想知道每个供应商销售多少个部件,我们可 [1] [2] 下一页 [Access]sql随机抽取记录 [Access]ASP&SQL让select查询结果随机排序的实现方法 [Web开发]SQL语句 SELECT LIKE like用法详解 [系统软件]SQL语句性能优化--LECCO SQL Expert [C语言系列]SQL Server到DB2连接服务器的实现 [C语言系列]SQL Server到SYBASE连接服务器的实现 [C语言系列]SQL Server到SQLBASE连接服务器的实现 [C语言系列]SQL Server连接VFP数据库的实现 [C语言系列]ASP+SQL Server之图象数据处理 [C语言系列]SQL Server连接ACCESS数据库的实现
|