GBase8s 数据库连接查询简介
表1 客户表(customer)实例数据
|
客户编号 customer_num |
姓名 c name |
单位 c ompany |
地址 a ddress |
城市 c ity |
国家 s tate |
电话 p hone |
|
1 01 |
张一川 |
金牌大风 |
解放路1 8 号 |
香港 |
中国 |
1 3887898075 |
|
1 02 |
李凤 |
华谊兄弟 |
光明路1 9 号 |
北京 |
中国 |
1 3058221289 |
|
1 03 |
王宝强 |
乔杰力娱乐 |
中华路8 8 号 |
北京 |
中国 |
1 5853284543 |
|
1 04 |
杰克 |
新索娱乐 |
卡梅尔路4 22 号 |
洛杉矶 |
美国 |
4 157433611 |
|
1 05 |
刘杰 |
|
复兴路3 8 号 |
北京 |
中国 |
1 8853898789 |
表2 订单表(orders)实例数据
|
订单编号 order_num |
客户编号 customer_num |
订单日期 order_date |
交易日期 s hip_date |
付款日期 p aid_date |
|
1 001 |
1 01 |
0 5 / 20 / 2014 |
0 6/01/2014 |
0 7/22/2014 |
|
1 002 |
1 01 |
0 5 / 21 / 2014 |
0 5/26/2014 |
0 6/03/2014 |
|
1 003 |
1 04 |
0 5 / 22 / 2014 |
0 5/23/2014 |
0 6/14/2014 |
|
1 004 |
1 02 |
0 6 / 07 / 2014 |
0 7/06/2014 |
0 7/21/2014 |
|
1 005 |
1 04 |
0 6 / 22 / 2014 |
0 7/10/2014 |
0 7/31/2014 |
表3 订单明细表(item s )实例数据
|
订单明细编号 i tem_num |
订单编号 o rder_num |
商品名称 s hip_name |
商品单价 s hip_price |
数量 q uantity |
|
1 0001 |
1 001 |
商品H RO |
2 50.0 |
1 |
|
1 0002 |
1 002 |
商品H SK |
9 60.0 |
2 |
|
1 0003 |
1 002 |
商品H SKA |
2 40.0 |
3 |
|
1 0004 |
1 003 |
商品A NZA |
1 9.8 |
5 |
|
1 0005 |
1 004 |
商品H RO |
2 50.0 |
1 |
|
1 0006 |
1 005 |
商品H RR |
4 80.0 |
5 |
1. 内连接 (join on)
1) 说明
内连接只返回两个表中与连接谓词匹配的行,不匹配的行不会被输出。
2) 举例
Ø 问题: 查询每位顾客的联系方式及其订货日期
Ø 分析: 顾客信息存放在customer表中,订单日期存放在orders表中,本查询需要涉及两个表,两个表之间的联系是通过customer表的主键customer_ num 和orders表的外键customer _num 实现的。
Ø 查询语句:
select customer.customer_num, cname, phone, order_num, order_date
f rom customer join orders
o n customer.customer_num=orders.customer_num;
Ø 查询结果:
|
custom er_num |
c name |
p hone |
o rder_num |
o rder_date |
|
1 01 |
张一川 |
1 3887898075 |
1 001 |
0 5 / 20 / 2014 |
|
1 01 |
张一川 |
1 3887898075 |
1 002 |
0 5 / 21 / 2014 |
|
1 04 |
杰克 |
4 157433611 |
1 003 |
0 5 / 22 / 2014 |
|
1 02 |
李凤 |
1 3058221289 |
1 004 |
0 6/07/2014 |
|
1 04 |
杰克 |
4 157433611 |
1 005 |
0 6 / 22 / 2014 |
2. 外连接
内连接操作的结果只输出两个表中在连接谓词上匹配的行。如果希望连接操作将左表或者右表中不匹配的行也输出,就需要使用外连接了。外连接分为左外连接、右外连接和完全外连接。
2.1 左外连接(left outer join on )
1) 说明:
左外连接会返回左表中全部的行,即使右表中没有找到匹配的行。如果左表中的行在右表中没有匹配的行,对应的行上来自右表的属性为空值。
2) 举例:
Ø 问题: 查询每位顾客的订购物品的信息,目前没有订单的顾客也要列出
Ø 分析: 顾客信息在customer表中,物品的信息在orders表中,两个表通过customer表中的主键customer _num 和orders表中的外键customer _num 连接。
Ø 查询语句:
select customer .customer_num, cname, phone, order_num,order_date
f rom customer left outer join orders
o n customer.customer_num=orders.customer_num;
Ø 查询结果:
|
c ustomer_num |
c name |
p hone |
o rder_num |
o rder_date |
|
1 01 |
张一川 |
1 3887898075 |
1 001 |
0 5 / 20 / 2014 |
|
1 01 |
张一川 |
1 3887898075 |
1 002 |
0 5 / 21 / 2014 |
|
1 02 |
李凤 |
1 3058221289 |
1 004 |
0 6 / 07 / 2014 |
|
1 03 |
王宝强 |
1 5853284543 |
|
|
|
1 04 |
杰克 |
4 157433611 |
1 003 |
0 5 / 22 / 2014 |
|
1 04 |
杰克 |
4 157433611 |
1 005 |
0 6 / 22 / 2014 |
|
1 05 |
刘杰 |
1 8853898789 |
|
|
2.2 右外连接( right outer join on )
1) 说明:
右外连接会返回左表中全部的行,即使左表中没有找到匹配的行。如果右表中的行在左表中没有匹配的行,对应的行上来自左表的属性为空值。
2) 举例:(与左连接类似,不再列举)
Ø 问题: 查询每位顾客的订购物品的信息,目前没有订单的顾客也要列出
Ø 分析: 顾客信息在customer表中,物品的信息在orders表中,两个表通过customer表中的主键customer _num 和orders表中的外键customer _num 连接。
Ø 查询语句:(使用右外连接,修改左右表位置即可)
select customer .customer_num, cname, phone, order_num,order_date
f rom orders left outer join customer
o n orders.customer_num= customer .customer_num;
Ø 查询结果:
|
c ustomer_num |
c name |
p hone |
o rder_num |
o rder_date |
|
1 01 |
张一川 |
1 3887898075 |
1 001 |
0 5 / 20 / 2014 |
|
1 01 |
张一川 |
1 3887898075 |
1 002 |
0 5 / 21 / 2014 |
|
1 02 |
李凤 |
1 3058221289 |
1 004 |
0 6 / 07 / 2014 |
|
1 03 |
王宝强 |
1 5853284543 |
|
|
|
1 04 |
杰克 |
4 157433611 |
1 003 |
0 5 / 22 / 2014 |
|
1 04 |
杰克 |
4 157433611 |
1 005 |
0 6 / 22 / 2014 |
|
1 05 |
刘杰 |
1 8853898789 |
|
|
3. 自连接(self- join )
1) 说明:
自连接是指一个表与自身进行连接操作,它是特殊形式的内连接。
2) 举例:
Ø 问题: 查询提交了一次以上订单的顾客信息
Ø 分析: 在订单表o rders 中查看拥有不同的订单的同一个顾客的信息,将customer _num 输出。
该例中将orders表按照customer _num 属性等值进行了连接,由于连接的两个表名字相同,无法使系统区分何时调用哪张表,因此需要为两张表取别名A和B ,按照要在同一行中出现不同的订单号,就说明该顾客至少签订了两个订单,通过A . order _num<>B.order_num 条件可以过滤掉同一行订单记录自身匹配的情况。
Ø 查询语句:
select distin ct A.customer_num
f rom orders A inner join orders B on A.customer_num=B.customer_num
w here A.order_num<>B.order_num;
或
select dis tinct A.customer_num
f rom orders A, orders B
w here A.customer_num=B.customer_num a nd A.order_num <>B.order_num;
或(不用连接查询,使用嵌套查询)
select A.customer_num, count(*)
f rom orders
g roup by customer_num having count(*) >1;
Ø 查询结果:
|
c ustomer_num |
|
1 01 |
|
1 04 |
4. 多表连接
1) 说明:
将两个以上的表进行连接的操作称为多表连接。连接多张表需要使用多个join关键字。可以将多表连接的执行过程理解为:第1张表与第2张表连接,将得到的中间结果表再与第3张表连接,依此类推,直到获得最终结果表。
2) 举例:
Ø 问题: 查询每位顾客提交订单的日期、所定的物品名称及物品价格
Ø 分析: 由于内连接运算满足交换律和结合律,多张表的连接顺序不会改变结果表,所以D BMS 不一定按照表的先后顺序依次执行连接,而是根据执行代价选择最优的连接顺序。
Ø 查询语句:
select cname , order_date, ship_name, (ship_price * quantity) as total_price
f rom customer join orders
o n customer.customer_num=orders.customer_num join items on orders.order_num=items.order_num;
或
selec t cname, order_date, ship_name, (ship_price * quantity) as total_price
f rom customer , orders , items
w here customer.customer_num=orders.customer_num and orders.order_num=items.order_num;
Ø 查询结果:
|
c name |
o rder_date |
s hip_name |
t otal_price |
|
张一川 |
0 5 / 20 / 2014 |
商品H RO |
$2 50.00 |
|
张一川 |
0 5 / 21 / 2014 |
商品H SK |
$ 1920.00 |
|
张一川 |
0 5 / 21 / 2014 |
商品H SKA |
$ 720.00 |
|
杰克 |
0 5 / 22 / 2014 |
商品A NZA |
$ 99.00 |
|
李凤 |
0 6 / 07 / 2014 |
商品H RO |
$ 250.00 |
|
杰克 |
0 6 / 22 / 2014 |
商品H RR |
$ 2400.00 |