这部分又划分了两部分内容:书上例题与课后习题
第五章书上例题:数据库Sales
其中的四张数据库表:
aid | aname | city | percent |
---|---|---|---|
a01 | Smith | NY | 6 |
a02 | Jones | Newark | 6 |
a03 | Brown | TY | 7 |
a04 | Gray | NY | 6 |
a05 | Otasi | Duluth | 5 |
a06 | Smith | Dallas | 5 |
cid | cname | city | discnt |
---|---|---|---|
c001 | TipTop | Duluth | 10.00 |
c002 | Basics | Dallas | 12.00 |
c003 | Allied | Dallas | 8.00 |
c004 | ACME | Duluth | 8.00 |
c006 | ACME | Tokyo | 0.00 |
pid | pname | city | quantity | price |
---|---|---|---|---|
p01 | comb | Dallas | 1290000 | 0.5 |
p02 | brush | Newark | 2319000 | 0.5 |
p03 | razor | Duluth | 1200000 | 1.0 |
p04 | pen | Duluth | 2390001 | 1.0 |
p05 | pencil | Dallas | 2311100 | 1.0 |
p06 | folder | Dallas | 1231000 | 2.0 |
p07 | case | Newark | 1000500 | 1.0 |
ordno | month | cid | aid | pid | qty | dollars |
---|---|---|---|---|---|---|
1011 | jan | c001 | a01 | p01 | 1000 | 312 |
1012 | jan | c001 | a01 | p01 | 1000 | 223 |
1013 | jan | c002 | a03 | p03 | 1000 | 123 |
1017 | feb | c001 | a06 | p03 | 600 | 123 |
1018 | feb | c001 | a03 | p04 | 600 | 435 |
1019 | feb | c001 | a02 | p02 | 400 | 323 |
1022 | mar | c001 | a05 | p06 | 400 | 242 |
1023 | mar | c001 | a04 | p05 | 500 | 241 |
1025 | apr | c001 | a05 | p07 | 800 | 132 |
1026 | mar | c002 | a05 | p03 | 800 | 345 |
看起来就很多,很烦,别担心,做题会更烦。不过仍然要加油鸭!
eg1:基于数据库Sales,创建用户自定义数据类型agentName。它基于varchar(8),不允许为空。数据库语句如下:
use sales
exec sp_addtype 'agentname','varchar(8)','not null'
go
eg2:删除用户自定义数据类型agentName
use sales
exec sp_droptype 'agentname'
go
eg3:创建数据库
create database sales
eg4:删除数据库
drop database sales
eg5:以具有代表性的ORDER表来写出创见它的数据库语句:
create table orders{
ordno nvarchar(255) not null,
month nvarchar(255) not null,
cid nvarchar(255) not null,
aid nvarchar(255) not null,
pid nvarchar(255) not null,
qty float,
[dollars] float, -------表级完整性约束条件前的属性,有框(规律总结出的,并非官方解释)
primary key(ordno) --------表级完整性约束,设置主键
foreign key(cid) references customers(cid) --------表级完整性约束,设置外键(即cid不是order主键,但是是customers的主键)
foreign key(aid) references customers(aid) --------表级完整性约束,设置外键
foreign key(pid) references customers(pid) --------表级完整性约束,设置外键
}
eg6:将表customers中的姓名(cname)的列长度改为20,数据库语句如下:
alter table customers
alter column cname varchar(20)
eg7:向数据表agents中增加电子信箱email列,列名:email,数据类型:char,长度:40,不允许空
alter table agents
add email char(40) not null
eg8:删除agents中的email列
alter table agents
drop column email
eg9:删除订购表orders
drop table orders
eg10:使用语句查询代理商和顾客不在同一城市的代理商编号和顾客编号
select aid,pid
from agents,customers
where agents.city<>customers.city
eg11:查询全体顾客的详细记录:
select * from customers
eg12:查询全部产品的编号(pid),名称(pname)、单价(price)
select pid,pname,price from products
eg13:查询订货记录中的所有产品pid
select pid from orders
eg14:查询订货记录中所有产品的pid,并保证pid的唯一性
select distinct pid from orders
eg15:查询全部产品的名称(pname)、库存的总金额
select pname, quantity *price totalqty from products -----此处注意, quantity *price是计算表达式,totalqty是别名,表示总金额的列标题。 此语句得到两列,pname和totalqty
eg16:查询居住在纽约(NY)的代理商编号(aid)和姓名(aname)
select aid,aname from agents where city='NY'
eg17:查询单价(price)在5-10元之间的产品名称
select pid from products where price between 5 and 10
eg18:查询产品单价(price)大于5且小于8的产品信息
select * from products where price >5 and price <8
eg19:查询居住在纽约(NY)或Dallas的顾客的编号(cid)、姓名(cname)、城市(city)
select cid,cname,city from customers where city='NY' or city='Dallas'
eg20: 从Agents表中查询居住在纽约或者佣金(percent)小于6的代理商编号(aid)和姓名(aname)
select aid,aname from agents where city='NY' or [percent]<6
首先了解一下通配符
通配符 | 描述 | 示例 |
---|---|---|
% | 包含0个或者更多的任意字符串 | where cname like '%abc%'----查找姓名包括abc的顾客 |
_(下划线) | 任何单个字符 | |
[ ] | 属于指定范围([a-f])或集合[aswdwd]中的任意单个字符 | |
[^ ] | 不属于指定范围(如:[a-f])或者集合([xsado])中的任一单个字符 |
eg21:查询姓名(cname)以字母‘A’开始的顾客的所有信息
select * from customers where cname like 'A%';
eg22:查询姓名(cname)的第三个字母不等于“%”的顾客编号(cid)和姓名(cname)
select cname from customers where cname not like '_ _ \%%'escape ' \ '; 注:'\'后的第一个%按本身含义来解释,第二个%是通配符。
eg23:(空值的处理)查询尚未输入城市(city)值的顾客信息。
select * from customers where city is null;
首先了解一下SQL提供的主要五个聚合函数
函数名 | 作用 |
---|---|
count | 统计组中的项数(多少行?与列的数据类型无关)----count(*)返回总行数 |
sum | 返回表达书中所有值的和或仅非重复值的和,sum只能用于数字列,NULL会被忽略 |
avg | 返回组中各值的平均值,只用于数字列,忽略空值 |
max | 求一列值的最大值,不允许使用聚合函数和子查询 |
min | 求一列值的最小值,不允许使用聚合函数和子查询 |
eg24:查询有顾客居住的城市数。
select count(distinct city) as num from customers
eg25:查询所有订货交易的总金额
select sum(dollars) as totalmoney from orders
eg26:查询所有产品的平均价格
select avg(price) as avgprice from products
eg27:查询订购表中最高的订购总价
select max(dollars) from orders
eg28:查询代理商表中最低的佣金
select min([percent]) from agents
eg29:查询所有顾客信息,并按名字升序排序
select * from customers order by cname asc;
eg30:查询每种产品的订购总量
select pid,sum(qty) as totalqty from orders group by pid
eg31:查询各个代理商订购的某种产品的总量
select aid,pid,sum(qty) as totalqty from orders group by aid,pid
eg32:查询满足条件为某个代理商所订购的某种产品的总量超过1000的产品ID,代理商ID和总量
select aid,pid,sum(qty) as totalqty from orders group by aid,pid having sum(qty)>1000
eg33:查询被至少两个顾客订购的所有产品的pid值
select pid from orders group by pid having count(distinct aid)>=2
eg34:查询所有满足条件“顾客通过代理商订了货”的顾客代理商名字组合
select cname,aname from agents,customers,orders where customers.cid=orders.cid and orders.aid=agents.aid
eg35:查询居住在同一城市的所有顾客对
select c1.cid cid1,c2.cid cid2 from cutomers c1,cutomers c2 where c1.city=c2.city and c1.cid<c2.cid
注:cid1,cid2,c1,c2均为别名
eg36:查询订购了某个被代理商a06代理过的产品的所有顾客的cid值
select distinct y.cid from orders x,orders y where y.aid=x.aid and x.aid='a06'
eg37:查询至少订购了一件价格低于¥0.6商品的所有顾客的名字
select distinct cname
from ((orders o join (select pid from products where price<0.6) p
on p.pid=o.pid join customers c on c.cid=o.cid ) 注:o, c, p均为表orders/customers/products别名
eg38:查询通过居住在Duluth或Dallas代理商订货的所有顾客的cid
select distinct c.cid
from agents a,orders o
where a.aid=o.aid and (a.city='Duluth' or a.city='Dalllas')
eg39:查询既订购了产品p01又订购了产品p07的顾客的cid值
select distinct o1.cid
from orders o1, orders o2
where o1.pid='p01' and o1.cid=o2.cid and o2.pid='p07'
eg40:查询满足条件“顾客通过代理商订了货”的顾客-代理商姓名组合
select distinct c.cname,a.aname
from (customers c join orders o on c.cid=o.cid) join agents a on a.aid=o.aid
eg41:(外连接)查询所有顾客的cid、cname、pid、qty。没有订购过的产品的顾客订购信息为空
select c.cid,c.cname,o.pid,o.qty
from orders o right outer join customers c on c.cid=o.cid
eg42:查询通过居住在Duluth或Dallas的代理商订货的所有顾客的cid
select cid from orders where in aid(select aid from agents where city='Duluth' or city='Dallas')
eg43:查询没有通过居住在Duluth或Dallas的代理商订货的所有顾客的cid
select cid from orders where not in aid(select aid from agents where city='Duluth' or city='Dallas')
eg44:查询折扣值小于最大折扣值的所有顾客的cid
select cid from cutomers where discnt < (select max(discnt) from cutomers);
eg45:查询至少被两个顾客订购的产品
select pid from products p where 2<=(select count(distinct cid)from orders where pid=p.pid)
eg46:查询佣金百分率最小的代理商aid值
select aid from agents where [percent]<=all (select [percent] from agents)
eg47:查询与居住在Dallas或Boston的顾客拥有相同折扣的所有顾客
select aid from customers where discnt = all (select discnt from customers where city='Dallas' or 'Boston')
eg48:查询既订购了产品p01又订购了产品p07的顾客的cid
select distinct cid from orders x
where pid='p01' and cid in (select cid from orders where pid='p07')
eg49:查询既订购了产品p01又订购了产品p07的顾客的cid值。(EXISTS---不返回实际数据,只产生真值或逻辑假值)
select distinct cid from orders x
where pid='p01' and exists (select * from orders where cid=x.cid and pid='p07')
eg50:查询没有通过代理商a05订货的所有顾客名字
select distinct cname from customers c
where not exists(select * from orders where c.cid=cid and aid='a05')
eg51:查询得到顾客所居住的城市、代理商所在城市或者两者都在的城市
select city from customers union select city from agents (如果用union all,会返回包括重复行)
eg52:查询既订购了产品p01又订购了产品p07的顾客cid值
select cid from orders where pid='p01' union select cid from orders where pid='p07'
eg53:查询没有通过代理商a05订货的所有顾客的姓名
select c.cname from customers c except select c.cname from customers c,orders o where(c.cid=x.cid and x.aid='a05')
eg54:查询订购了所有产品的顾客的cid (题解:转换成不存在一个产品顾客没有订购)
select