一、基本结构
1、select字句
如果显式删除重复的记录,可以使用如下:
select distinct branch_name
from loan
如果显式指明不删除重复(默认时就是不删除):
select all branch_name
from loan
select字句可以带加减乘除运算符号:
select branch_name, loan_number, amount*100
from loan
2、where字句
字句中可以使用and or not逻辑运算,表示且、或、非。
select loan_number
from loan
where branch_name = "PerryBridge" and amout >1200
where字句还可以使用between运算:
select loan_number
from loan
where amout between 9000 and 12000
用上面的语句可以替代下面的语句:
select loan_number
from loan
where amout >= 9000 and amout <=12000
同理,可以使用 not between。
3、from字句
from字句定义的是笛卡儿积。例如,“找出银行贷款中所有用户的名字和贷款号”:
select distinct customer_name, borrower.loan_number
from borrower, loan
where borrower.loan_number = loan.loan_number
“找出在PerryBridge银行有贷款的所有用户的名字和贷款号”:
select distinct customer_name, borrower.loan_number
from borrower, loan
where borrower.loan_number = loan.loan_number and branch_name = "PerryBridge"
4、更名运算:
①from字句中两个表中有相同的属性,这样在结果中会有属性名相同
②select字句中,如果属性使用了算术表达式,这样属性就没有名字了
③像上例中,属性名可以从基本关系中得到,我们可以在结果中改名字
改名运算:
old-name as new-name
例如:
select distinct customer_name, borrower.loan_number as loan_id
from borrower, loan
where borrower.loan_number = loan.loan_number and branch_name = "PerryBridge"
5、元组变量
通过from字句中使用as实现,例如,重新写“找出银行贷款中所有用户的名字和贷款号”:
select distinct customer_name, S.loan_number
from borrower as T, loan as S
where T.loan_number = S.loan_number
实际上,使用relation_name.attribute_name时,关系名就是隐含的元组变量。
元组变量在比较同一个关系中两个元组时比较重要,例如“找出资产至少比位于Brooklyn的某一家分支机构高的分支机构”:
select distinct T.branch_name
from branch as T, branch as S
where T.assets > S.assets and S.branch_name = "Brooklyn"
6、字符串操作:
最常用的就是like的模式匹配:
①:百分号(%)——匹配任意子串;
②:下划线(_)——匹配任意一个字符。
模式匹配是大小写敏感的。有以下例子:
"Perry%"——匹配任何以Perry开头的字符串;
"%idge%"——匹配任何包含idge的字符串,例如Perryidge,Rock Ridge等等;
"_ _ _"——匹配只含有三个字符的字符串;
"_ _ _%"——匹配至少含有三个字符的字符串。
例如,“找出街道地址中包含所有子串‘Main’的所有客户名”:
select customer_name
from customer
where customer_street like "%Main%"
如果要匹配%,_ 就需要使用转义字符(\)了,例如:
like "ab\%cd%" escape "\" ——匹配所有以ab%cd开头的字符串;
like "ab\\cd%" escape "\"——匹配所有以ab\cd开头的字符串;
SQL中还允许使用 not like 搜寻不匹配项。还允许在字符串上使用多种函数,例如连接(||)、提取子串,计算字符串长度、大小写转换等
7、排列记录的显示次序
使用order by字句,缺省使用升序。例如:“按字母顺序列出在Perryidge分支机构中有贷款的客户”:
select distinct customer_name
from borrower, loan
where borrower.loan_number = loan.loan_number and branch_name = "Perryidge"
order by customer_name
如果要说明顺序,可以用desc表示降序,asc表示升序。排序可以在多个属性上进行,例如:希望loan按amount降序排列,如果有相同的贷款额,则按贷款号升序排列:
select *
from loan
order by amount desc, loan_number asc
排序操作代价很大,不要万不得已 最好不要排序。
二、集合操作
这里主要讲解关系上的并、交、差,对应的关键字是union、intersect、except。
1、并操作
找出在银行有账户、贷款或者两者兼有的所有客户:
(select customer_name
from depositer)
union [all]
(select customer_name
from borrower)
union能自动去掉重复,如果要显式保留重复,可以在union后加一个all
2、交操作
找出在银行同时有账户和贷款的所有客户:
(select customer_name
from depositer)
intersect [all]
(select customer_name
from borrower)
all能显式不删除重复
3、差操作
找出在银行中有账户但没有贷款的用户名:
(select customer_name
from depositer)
expect [all]
(select customer_name
from borrower)
三、聚集函数
聚集函数是以一个值集合为输入,返回单个值的函数。SQL提供了5个预定义的函数:求平均值avg、最大值max、最小值min、总和sum、计数count。
sum和avg的输入必须是数字,其他的可以是非数字的数据类型如字符串上。
找出分支机构Perryidge所有账户余额的平均值:
select avg(balance)
from account
where branch_name = "Perryidge"
该查询只有一个属性,记录只有一条。有时也希望聚集函数作用在某一组元组的集上,用group by 实现分组,在group by字句中的一个或多个属性是用来构造分组的。它将所有属性相同的值的元组放在一个分组里。
例如:找出每一个分支机构的账户结算平均值:
select branch_name, avg(balance) as avg_balance
from account
group by branch_name
有时计算聚集函数前需要删掉重复元组,这时需要使用关键字distinct。找出每个分支机构的储户数:
select branch_name, count (distinct customer_name)
from depositor, account
where depositor.account_number = account.account_number
group by branch_name
having子句是在形成分组之后才起作用,因此可以使用聚集函数,例如,只显示账户平均结算余额大于1200的账户:
select branch_name, avg(balance)
from account
group by branch_name
having avg(balance) > 1200
使用count(*)来计算关系中元组的个数:
select count(*)
from customer
四、嵌套子查询
1、集合成员资格
找出银行中同时又账户和贷款账户的人:
select distinct branch_name
from borrower
where customer_name in ( select customer_name
from depositor )
找出在分支机构Perryidge同时有账户和贷款的客户:
select distinct customer_name
from borrower, loan
where borrower.loan_number = loan.loan_number and
branch_name = "Perridge" and
(branch_name, customer_name) in
(select branch_name, customer_name
from depositor, account
where depositor.account_number = account.account_number)
not in 可以测试成员不在集合中
2、集合比较
至少比一个大 用 >some. 例如:找出那些总资产至少比位于Brooklyn的某一家分支机构要多的分支机构的名字:
用以前的方法是:
select distinct T.branch_name
from branch as T, branch as S
where T.assets > S.assets and S.branch_city = "Brooklyn"
用>some的写法是:
select branch_name
from branch
where assets > some ( select assets
from branch
where branch_city = "Brooklyn")
还有 <some, <=some, >=some, =some(等价于in), , <>some(不等价于not in)
比所有都大用 >all.例如:
select branch_name
from branch
where assets > all ( select assets
from branch
where branch_city = "Brooklyn")
同理有>all, >= all, <all, <=all, =all, <>all(这个等价于not in)
例如:找出平均余额最大的分支机构:
SQL中的聚集函数不能复合使用,也就是说不能这样使用:max ( avg(....)),那么我们可以先求出每个银行的平均余额,再找出平均余额大于等于所有分支机构的余额的机构:
select branch_name
from account
group by branch_name
having avg (balance) >= all ( select avg (balance)
from account
group by branch_name)
3、测试是否为空关系
4、测试是否存在重复元组
unique 与not unique
五、派生关系
等着派生关系
六、视图
等着补充视图
七、数据库的修改
1、删除
delete from p
where r
delete from p 可以删除整张表的内容
2、插入
insert into account (branch_name, account_number, balance)
values ( "Perridge", "A-9732", 1200 )
3、更新
update account
set balance = balance*10
where balance > 1200
4、视图更新