select 语法
来源:互联网 发布:淘宝砖石展位 编辑:程序博客网 时间:2024/05/29 11:43
SQL 里面最常用的命令是 SELECT 语句,用于检索数据。语法是: 现在我们将通过不同的例子演示 SELECT 语句复杂的语法。用于这些例子的表在 供应商和部件数据库 里定义。 这里是一些使用 SELECT 语句的简单例子: Example 1-4. 带有条件的简单查询 要从表 PART 里面把字段 PRICE 大于 10 的所有记录找出来, 我们写出下面查询: 在 SELECT语句里使用 "*" 将检索出表中的所有属性。 如果我们只希望从表 PART 中检索出属性 PNAME 和 PRICE, 我们使用下面的语句: WHERE 子句里的条件也可以用关键字 OR,AND,和 NOT 逻辑地连接起来: 目标列表和 WHERE 子句里可以使用算术操作。例如, 如果我们想知道如果我们买两个部件的话要多少钱, 我们可以用下面的查询: 下面的例子显示了 SQL 里是如何实现连接的。 要在共同的属性上连接三个表 SUPPLIER,PART 和 SELLS, 我们通常使用下面的语句: 在 FROM 子句里,我们为每个关系使用了一个别名, 因为在这些关系间有着公共的命名属性(SNO 和 PNO)。 现在我们可以区分不同表的公共命名属性, 只需要简单的用每个关系的别名加上个点做前缀就行了。 联合是用与 一个内部联接 里显示的同样的方法计算的。首先算出笛卡儿积 SUPPLIER × PART × SELLS 。然后选出那些满足 WHERE 子句里给出的条件的记录 (也就是说,公共命名属性的值必须相等)。 最后我们映射出除 S.SNAME 和 P.PNAME 外的所有属性。 另外一个进行连接的方法是使用下面这样的 SQL JOIN 语法: 一个用 JOIN 语法创建的连接表,是一个出现在 FROM 子句里的, 在任何 WHERE,GROUP BY 或 HAVING 子句之前的表引用列表项. 其它表引用,包括表名字或者其它 JOIN 子句,如果用逗号分隔的话, 可以包含在 FROM 子句里. 连接生成的表逻辑上和任何其它在 FROM 子句里列出的表都一样. SQL JOIN 有两种主要类型,CROSS JOIN (无条件连接) 和条件连接.条件连接还可以根据声明的 连接条件(ON,USING,或 NATURAL)和它 应用的方式(INNER 或 OUTER 连接)进一步细分. 连接类型 { 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. { 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. 小技巧: 连接成的表无条件地包含 T1 里的所有行. RIGHT [ OUTER ] JOIN 首先,执行一次 INNER JOIN. 然后,如果 T2 里有一行对任何 T1 的行都不满足 连接条件,那么返回一个连接行,该行的 T1 的字段 为 null. 小技巧: 连接成的表无条件地包含 T2 里的所有行. FULL [ OUTER ] JOIN 首先,执行一次 INNER JOIN. 然后,如果 T1 里有一行对任何 T2 的行都不满足 连接条件,那么返回一个连接行,该行的 T1 的字段 为 null. 同样,如果 T2 里有一行对任何 T1 的行都不满足 连接条件,那么返回一个连接行,该行的 T2 的字段 为 null. 小技巧: 连接成的表无条件地拥有来自 T1 的每 一行和来自 T2 的每一行. 所有 类型的 JOIN 都可以链接在一起或者嵌套在一起, 这时 T1 和 T2 都可以是连接生成的表.我们可以使用圆括弧控制 JOIN 的顺序,如果我们不主动控制,那么连接顺序是从左到右. SQL 提供以一些聚集操作符(如, AVG,COUNT,SUM,MIN,MAX),这些聚集操作符以一个表达式为参数。 只要是满足 WHERE 子句的行,就会计算这个表达式, 然后聚集操作符对这个输入数值的集合进行计算. 通常,一个聚集对整个 SELECT 语句计算的结果是 生成一个结果.但如果在一个查询里面声明了分组, 那么数据库将对每个组进行一次独立的计算,并且 聚集结果是按照各个组出现的(见下节). Example 1-5. 聚集 果我们想知道表 PART 里面所有部件的平均价格,我们可以使用下面查询: 结果是: 如果我们想知道在表 PART 里面存储了多少部件,我们可以使用语句: SQL 允许我们把一个表里面的记录分成组。 然后上面描述的聚集操作符可以应用于这些组上 (也就是说,聚集操作符的值不再是对所有声明的列的值进行操作, 而是对一个组的所有值进行操作。这样聚集函数是为每个组独立地进行计算的。) 对记录的分组是通过关键字 GROUP BY 实现的,GROUP BY 后面跟着一个定义组的构成的属性列表。 如果我们使用语句 GROUP BY A1, ⃛, Ak 我们就把关系分成了组,这样当且仅当两条记录在所有属性 A1, ⃛, Ak 上达成一致,它们才是同一组的。 Example 1-6. 聚集 如果我们想知道每个供应商销售多少个部件,我们可以这样写查询: 然后我们看一看发生了什么事情。首先生成表 SUPPLIER 和 SELLS 的连接: 然后我们把那些属性 S.SNO 和 S.SNAME 相同的记录放在组中: 在我们的例子里,我们有四个组并且现在我们可以对每个组应用聚集操作符 COUNT,生成上面给出的查询的最终结果。 请注意如果要让一个使用 GROUP BY 和聚集操作符的查询的结果有意义, 那么用于分组的属性也必须出现在目标列表中。 所有没有在 GROUP BY 子句里面出现的属性都只能通过使用聚集函数来选择。 否则就不会有唯一的数值与其它字段关联. 还要注意的是在聚集上聚集是没有意义的,比如,AVG(MAX(sno)), 因为 SELECT 只做一个回合的分组和聚集.你可以获得这样的结果, 方法是使用临时表或者在 FROM 子句中使用一个子 SELECT 做第一个层次的聚集. HAVING 子句运做起来非常象 WHERE 子句, 只用于对那些满足 HAVING 子句里面给出的条件的组进行计算。 其实,WHERE 在分组和聚集之前过滤掉我们不需要的输入行, 而 HAVING 在 GROUP 之后那些不需要的组. 因此,WHERE 无法使用一个聚集函数的结果. 而另一方面,我们也没有理由写一个不涉及聚集函数的 HAVING. 如果你的条件不包含聚集,那么你也可以把它写在 WHERE 里面, 这样就可以避免对那些你准备抛弃的行进行的聚集运算. Example 1-7. Having 如果我们想知道那些销售超过一个部件的供应商,使用下面查询: 在 WHERE 和 HAVING 子句里,允许在任何要产生数值的地方使用子查询 (子选择)。 这种情况下,该值必须首先来自对子查询的计算。子查询的使用扩展了 SQL 的表达能力。 Example 1-8. 子查询 如果我们想知道所有比名为 'Screw' 的部件贵的部件,我们可以用下面的查询: 结果是: 当我们检查上面的查询时会发现出现了两次 SELECT 关键字。 第一个在查询的开头 - 我们将称之为外层 SELECT - 而另一个在 WHERE 子句里面,成为一个嵌入的查询 - 我们将称之为内层 SELECT。 对外层 SELECT 的每条记录都必须先计算内层 SELECT。在完成所有计算之后, 我们得知名为 'Screw' 部件的记录的价格, 然后我们就可以检查那些价格更贵的记录了。 (实际上,在本例中,内层查询只需要执行一次, 因为它不依赖于外层查询高等状态.) 如果我们想知道那些不销售任何部件的供应商 (比如说,我们想把这些供应商从数据库中删除),我们用: 在我们的例子里,结果列将是空的,因为每个供应商至少销售一个部件。 请注意我们在 WHERE 子句的内层 SELECT 里使用了来自外层 SELECT 的 S.SNO。 正如前面所说的,子查询为每个外层查询计算一次,也就是说, S.SNO 的值总是从外层 SELECT 的实际记录中取得的。 一种有些特别的子查询的用法是把它们放在 FROM 子句里. 这个特性很有用,因为这样的子查询可以输出多列和多行, 而在表达式里使用的子查询必须生成一个结果. FROM 里的子查询还可以让我们获得多于一个回合的分组/聚集特性, 而不需要求助于临时表. Example 1-9. FROM 里面的子查询 如果我们想知道在所有我们的供应商中的最高平均部件价格的那家, 我们不能用 MAX(AVG(PRICE)),但我们可以这么写: 这些操作符分别计算两个子查询产生的元组的联合,相交和集合理论里的相异。 Example 1-10. Union, Intersect, Except 下面的例子是 UNION 的例子: 下面是相交( INTERSECT)的例子: 最后是一个 EXCEPT 的例子: 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 ]]
1.4.1.1. 简单的 Select
SELECT * FROM PART WHERE PRICE > 10;
然后得到表: PNO | PNAME | PRICE-----+---------+-------- 3 | Bolt | 15 4 | Cam | 25
SELECT PNAME, PRICE FROM PART WHERE PRICE > 10;
这回我们的结果是: PNAME | PRICE --------+-------- Bolt | 15 Cam | 25
请注意 SQL 的 SELECT 语句对应关系演算里面的 "projection" (映射),而不是 "selection"(选择)(参阅 关系演算 获取详细信息)。SELECT PNAME, PRICE FROM PART WHERE PNAME = 'Bolt' AND (PRICE = 0 OR PRICE <= 15);
这样将生成下面的结果: PNAME | PRICE--------+-------- Bolt | 15
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(连接)
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
select sname, pname from supplierJOIN 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)
1.4.1.3. 聚集操作符
SELECT AVG(PRICE) AS AVG_PRICE FROM PART;
AVG_PRICE----------- 14.5
SELECT COUNT(PNO) FROM PART;
得到: COUNT------- 4
1.4.1.4. 分组聚集
SELECT S.SNO, S.SNAME, COUNT(SE.PNO) FROM SUPPLIER S, SELLS SE WHERE S.SNO = SE.SNO GROUP BY S.SNO, S.SNAME;
得到: SNO | SNAME | COUNT-----+-------+------- 1 | Smith | 2 2 | Jones | 1 3 | Adams | 2 4 | Blake | 3
S.SNO | S.SNAME | SE.PNO-------+---------+-------- 1 | Smith | 1 1 | Smith | 2 2 | Jones | 4 3 | Adams | 1 3 | Adams | 3 4 | Blake | 2 4 | Blake | 3 4 | Blake | 4
S.SNO | S.SNAME | SE.PNO-------+---------+-------- 1 | Smith | 1 | 2-------------------------- 2 | Jones | 4-------------------------- 3 | Adams | 1 | 3-------------------------- 4 | Blake | 2 | 3 | 4
1.4.1.5. Having
SELECT S.SNO, S.SNAME, COUNT(SE.PNO) FROM SUPPLIER S, SELLS SE WHERE S.SNO = SE.SNO GROUP BY S.SNO, S.SNAME HAVING COUNT(SE.PNO) > 1;
and get: SNO | SNAME | COUNT-----+-------+------- 1 | Smith | 2 3 | Adams | 2 4 | Blake | 3
1.4.1.6. 子查询
SELECT * FROM PART WHERE PRICE > (SELECT PRICE FROM PART WHERE PNAME='Screw');
PNO | PNAME | PRICE-----+---------+-------- 3 | Bolt | 15 4 | Cam | 25
SELECT * FROM SUPPLIER S WHERE NOT EXISTS (SELECT * FROM SELLS SE WHERE SE.SNO = S.SNO);
1.4.1.7. 在 FROM 里面的子查询
SELECT MAX(subtable.avgprice) FROM (SELECT AVG(P.PRICE) AS avgprice FROM SUPPLIER S, PART P, SELLS SE WHERE S.SNO = SE.SNO AND P.PNO = SE.PNO GROUP BY S.SNO) subtable;
这个子查询为每个供应商返回一行(因为它的 GROUP BY) 然后我们在外层查询对所有行进行聚集.1.4.1.8. Union, Intersect, Except(联合,相交,相异)
SELECT S.SNO, S.SNAME, S.CITY FROM SUPPLIER S WHERE S.SNAME = 'Jones'UNION SELECT S.SNO, S.SNAME, S.CITY FROM SUPPLIER S WHERE S.SNAME = 'Adams';
产生结果: SNO | SNAME | CITY-----+-------+-------- 2 | Jones | Paris 3 | Adams | Vienna
SELECT S.SNO, S.SNAME, S.CITY FROM SUPPLIER S WHERE S.SNO > 1INTERSECT SELECT S.SNO, S.SNAME, S.CITY FROM SUPPLIER S WHERE S.SNO < 3;
产生结果: SNO | SNAME | CITY-----+-------+-------- 2 | Jones | Paris
两个查询都会返回的元组是那条 SNO=2 的SELECT S.SNO, S.SNAME, S.CITY FROM SUPPLIER S WHERE S.SNO > 1EXCEPT SELECT S.SNO, S.SNAME, S.CITY FROM SUPPLIER S WHERE S.SNO > 3;
结果是: SNO | SNAME | CITY-----+-------+-------- 2 | Jones | Paris 3 | Adams | Vienna
- select 语法
- SELECT语法
- select 语法
- SQL SELECT语法
- SQLite语法 SELECT
- SQL select 语法
- SQL select 语法
- SQLite Select 语法
- js select的语法
- SQL SELECT 语法
- SELECT语法详解
- SQL SELECT完整语法
- SELECT语句语法格式
- hive------select语法介绍
- sql select ... as...语法
- SELECT 基本语法
- hive中select语法
- MySQL的select语法
- java值传递与引用传递
- 抓取excel里某个sheet的数据到datagridview里
- 中电信低调推出微博网站
- 动态的tree ajax
- java单态模式讲解
- select 语法
- Linux/WinCE C、C++高端课程
- 提交多行数据到Struts的ActionForm的List属性中
- CString, BSTR, LPCTSTR 概念--leo断定->猛贴
- 程序员们纷纷表示“内牛满面”-VS2010视频共5季
- [C/C++] 把一个整型整数转成字符串
- vs2008验证控件的用法
- js 裁剪字符串
- C++中typename关键字的使用方法和注意事项