西游记吉他谱简单版:SQL

来源:百度文库 编辑:九乡新闻网 时间:2024/07/08 22:11:36
1、select子句
SQL查询语句的结果也是一个关系,例如:
Select branch-name from loan
找出了关系loan中所有分支机构的名称。
关系代数中基于关系是一个集合这样的数学概念,因此,重复的元组不会在关系中出现。但在实践当中,要删除查询结果中的重复元组是相当费时的!所以在商用数据库产品中,允许在关系和SQL表达式的结果中出现重复元组。对于select子句,还需要特别注意以下事情:
⑴是否要去除结果中的重复元组可以选用all和distinct选项,例如:
select [all | distinct] branch-name from loan
其中all表示保留所有重复元组,而distinct表示要去掉重复元组;
⑵可以用*代替关系中的所有属性,如loan.*或*:
select * from loan
⑶select子句中还可以出现算术表达式,这与关系代数中的广义投影运算对应:
select branch-name, loan-number, amount*100 from loan

2、where子句先
从一个例子开始,例如:
select loan-number from loan
where branch-name = "Perryridge" and amount>1200
这个SQL语句的含义是什么呢?请大家自己思考。
需要注意的是where子句中的逻辑运算符使用and、or和not,而不是∧、∨和?。比较运算符有<、<=、>、>=、=和<>。

3、from子句
from子句本身定义了子句中关系的笛卡尔积。由于自然连接是用笛卡尔积、选择和投影来定义的,因此为自然连接写SQL表达式还是相对简单的。例如:
关系代数表达式:Πcustomer-name, loan-number(borrowerloan)对应的SQL表达式如下所示:
select customer-name, borrower.loan-number
from borrower, loan
where borrower.loan-number = loan.loan-number

4、order by子句
用order by子句对查询的结果进行排序,具体的语法格式如下:order by 属性名 [asc | desc][,属性名 [asc | desc], ...]例如:
select * from loan
order by amount desc, loan-number 例如:
select customer-name, borrower.loan-number as loan-idfrom borrower, loan
where loan-id = loan.loan-number and branch-name = "Perryridge"
问题是我们为什么要更改属性名和关系名呢?理由如下:
⑴from子句中的多个关系里可能含有相同名字的属性要在select子句中出现;
⑵select子句中可能使用算术表达式;
⑶确实想以不同的名字作为查询结果的列首进行显示,例如,关系中的属性名可能太简单了;
⑷from子句中可能需要具有相同名字的多个关系参与连接运算。例如:
select T.customer-name, T.loan-number
from borrower as T, borrower as S
where T.loan-number = S.loan-number and T.customer-name <>
S.customer-name
这个SQL语句的含义,请大家自己思考。

这里的更名操作与第二章中的命名操作有些不同:命名操作只是对关系或关系代数表达式的操作,而这里的更名操作既可以对关系操作,也可以对属性进行更名。 如果我们要对定长的字符串进行整体匹配,可以用"=",否则只能用like操作符。另外字符串除了进行匹配之外,还可以按照字典顺序等进行比较,例如字符串"a">字符串"b"。
另外需要特别注意的是,字符串常量可以括在双引号中,也可以括在单引号中。如果习惯使用单引号,则一定要注意字符串本身的单引号的转义问题,因为在很多时候,字符串是需要用单引号的。例如:This is Feng's book。

本节的内容是SQL中最基本的也是最常用的,一定要熟练掌握,并多上机练习。

对于表达式:(r) {union | intersect | except} all (s)来说,使用all选项保留结果中的重复元组,那么,查询结果中一个元组的重复次数又是如何计算的呢?请看下面的解释:
⑴union all:查询结果中一个元组的重复次数是关系r与s中该元组重复次数的和;
⑵intersect all:查询结果中一个元组的重复次数是关系r与s里该元组重复次数中较少的那个次数;
⑶except all:查询结果中一个元组的重复次数是关系r与s中该元组重复次数的差。结果>0表明该元组在结果集里,否则(≤0)结果集里没有该元组。


例如:
select sum(balance) as Sum-Of-Balance
from account
where branch-name = "Perryridge"
在这里,我们需要强调的是SQL表达式中"*"的使用:
⑴一般来说,计算一个关系中元组的个数使用函数count(*),这时,绝对不能使用distinct选项;例如:
select count(*) from customer
select count(distinct customer-city) from customer
而select count(distinct *) from customer则是错误的语句。
⑵一般来说,表示关系中的所有属性使用符号"*",而为了找出一个关系中的不同元组则可以在"*"之前使用保留字distinct,例如:select * from customerselect distinct * from customer

聚集函数是不可以嵌套的,它的含义是说,在一个聚集函数的操作数中不能包含其他的聚集函数操作。


1、group by子句
group by子句根据一个或多个属性的值来对元组进行分组,如图4-4-1所示。聚集函数可以作用在不同的分组上,例如:select branch-name, sum(balance) as Summaryfrom accountgroup by branch-name

图4-4-1:关系account
2、having子句
having子句主要是针对分组进行条件限制。having子句中的谓词只有在形成分组后才起作用,因此可以在having子句中使用聚集函数。通常,having子句只用在有group by子句的SQL语句中,用来去掉不符合指定条件(即having子句中的谓词)的分组。例如:
select branch-name, sum(balance) as Summary
from account
group by branch-name
having avg(balance) > 1200
如果在同一个查询中同时存在where子句和having子句,那么首先应该用where子句中的谓词进行选择;满足where谓词的元组通过group by子句形成分组;然后在每个分组上使用having子句,不符合having谓词的分组将被抛弃掉!例如,找出居住在Harrison市且在银行中至少有三个帐户的客户的平均余额:
select d.customer-name, avg(balance) as Average-Balance
from depositor d, account a, customer c
where d.account-number = a.account-number and
d.customer-name = c.customer-name and
customer-city = "Harrison"
group by d.customer-name
having count(distinct d.account-number) >= 3