SQL中有三种联结,分别是:内联结,自然联结,外联结.
联结是针对不同表联合起来的一种方式.应用的对象是:表(table)
为了方便验证练习理解,首先展示所要用到的表的内容:
1.Customers表:
数据(可复制,创建表,插入数据):
CREATE TABLE Customers
(
cust_id char(10) NOT NULL ,
cust_name char(50) NOT NULL ,
cust_address char(50) NULL ,
cust_city char(50) NULL ,
cust_state char(5) NULL ,
cust_zip char(10) NULL ,
cust_country char(50) NULL ,
cust_contact char(50) NULL ,
cust_email char(255) NULL
);
-- ------------------------
-- Populate Customers table
-- ------------------------
INSERT INTO Customers(cust_id, cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact, cust_email)
VALUES('1000000001', 'Village Toys', '200 Maple Lane', 'Detroit', 'MI', '44444', 'USA', 'John Smith', '[email protected]');
INSERT INTO Customers(cust_id, cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact)
VALUES('1000000002', 'Kids Place', '333 South Lake Drive', 'Columbus', 'OH', '43333', 'USA', 'Michelle Green');
INSERT INTO Customers(cust_id, cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact, cust_email)
VALUES('1000000003', 'Fun4All', '1 Sunny Place', 'Muncie', 'IN', '42222', 'USA', 'Jim Jones', '[email protected]');
INSERT INTO Customers(cust_id, cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact, cust_email)
VALUES('1000000004', 'Fun4All', '829 Riverside Drive', 'Phoenix', 'AZ', '88888', 'USA', 'Denise L. Stephens', '[email protected]');
INSERT INTO Customers(cust_id, cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact)
VALUES('1000000005', 'The Toy Store', '4545 53rd Street', 'Chicago', 'IL', '54545', 'USA', 'Kim Howard');
-- ----------------------
展示:
2.Vendors:
-- -------------------
-- Create Orders table
-- -------------------
CREATE TABLE Orders
(
order_num int NOT NULL ,
order_date datetime NOT NULL ,
cust_id char(10) NOT NULL
);
-- ----------------------
-- Populate Vendors table
-- ----------------------
INSERT INTO Vendors(vend_id, vend_name, vend_address, vend_city, vend_state, vend_zip, vend_country)
VALUES('BRS01','Bears R Us','123 Main Street','Bear Town','MI','44444', 'USA');
INSERT INTO Vendors(vend_id, vend_name, vend_address, vend_city, vend_state, vend_zip, vend_country)
VALUES('BRE02','Bear Emporium','500 Park Street','Anytown','OH','44333', 'USA');
INSERT INTO Vendors(vend_id, vend_name, vend_address, vend_city, vend_state, vend_zip, vend_country)
VALUES('DLL01','Doll House Inc.','555 High Street','Dollsville','CA','99999', 'USA');
INSERT INTO Vendors(vend_id, vend_name, vend_address, vend_city, vend_state, vend_zip, vend_country)
VALUES('FRB01','Furball Inc.','1000 5th Avenue','New York','NY','11111', 'USA');
INSERT INTO Vendors(vend_id, vend_name, vend_address, vend_city, vend_state, vend_zip, vend_country)
VALUES('FNG01','Fun and Games','42 Galaxy Road','London', NULL,'N16 6PS', 'England');
INSERT INTO Vendors(vend_id, vend_name, vend_address, vend_city, vend_state, vend_zip, vend_country)
VALUES('JTS01','Jouets et ours','1 Rue Amusement','Paris', NULL,'45678', 'France');
-- -----------------------
3.Products:
-- ---------------------
-- Create Products table
-- ---------------------
CREATE TABLE Products
(
prod_id char(10) NOT NULL ,
vend_id char(10) NOT NULL ,
prod_name char(255) NOT NULL ,
prod_price decimal(8,2) NOT NULL ,
prod_desc text NULL
);
-- -----------------------
-- Populate Products table
-- -----------------------
INSERT INTO Products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('BR01', 'BRS01', '8 inch teddy bear', 5.99, '8 inch teddy bear, comes with cap and jacket');
INSERT INTO Products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('BR02', 'BRS01', '12 inch teddy bear', 8.99, '12 inch teddy bear, comes with cap and jacket');
INSERT INTO Products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('BR03', 'BRS01', '18 inch teddy bear', 11.99, '18 inch teddy bear, comes with cap and jacket');
INSERT INTO Products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('BNBG01', 'DLL01', 'Fish bean bag toy', 3.49, 'Fish bean bag toy, complete with bean bag worms with which to feed it');
INSERT INTO Products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('BNBG02', 'DLL01', 'Bird bean bag toy', 3.49, 'Bird bean bag toy, eggs are not included');
INSERT INTO Products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('BNBG03', 'DLL01', 'Rabbit bean bag toy', 3.49, 'Rabbit bean bag toy, comes with bean bag carrots');
INSERT INTO Products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('RGAN01', 'DLL01', 'Raggedy Ann', 4.99, '18 inch Raggedy Ann doll');
INSERT INTO Products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('RYL01', 'FNG01', 'King doll', 9.49, '12 inch king doll with royal garments and crown');
INSERT INTO Products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('RYL02', 'FNG01', 'Queen doll', 9.49, '12 inch queen doll with royal garments and crown');
4.Orders
-- -------------------
-- Create Orders table
-- -------------------
CREATE TABLE Orders
(
order_num int NOT NULL ,
order_date datetime NOT NULL ,
cust_id char(10) NOT NULL
);
-- ---------------------
-- Populate Orders table
-- ---------------------
INSERT INTO Orders(order_num, order_date, cust_id)
VALUES(20005, '2012-05-01', '1000000001');
INSERT INTO Orders(order_num, order_date, cust_id)
VALUES(20006, '2012-01-12', '1000000003');
INSERT INTO Orders(order_num, order_date, cust_id)
VALUES(20007, '2012-01-30', '1000000004');
INSERT INTO Orders(order_num, order_date, cust_id)
VALUES(20008, '2012-02-03', '1000000005');
INSERT INTO Orders(order_num, order_date, cust_id)
VALUES(20009, '2012-02-08', '1000000001');
好吧,如上原始数据已经有了,现在我们来理解SQL几种联结之间的关系和细节.
1.为什么要使用联结:
有时候为了方便存储,我们会把数据分解为多个表.例如,现在某公司需要用到以下产品,别人对应的供应商和价格如下:
这一张表存了供应商的信息和产品以及价格.可以看到这个供应商给我们提供了两种产品:QQ和邮箱;
这两种产品都是出自于同一个供应商,因此我们存储数据的时候,"供应商的地址"和"联系人" 就被重复存储了".现实应用中,一个供应商可能提供的产品远远超过2个,
这就会给我录入数据和存储数据和更新数据带来很大的麻烦.譬如:这个提供多种产品的供应商的地址需要更新的时候
于是我们可以把张表分解成两个表,关联两个表主键(方便查询,也就是相关联的共同的信息),如下:
1.
2.
这样一来,后续要我更新某个供应商的地址和联系人的时候,只需要对表2中的对应内容进行更新就好了.这样分解表后的两个表更直观一些了,但是在我们处理查询数据的时候,就要关联两个表中的
信息了,操作的复杂度就增大了.按照我们常规的处理方式,
如果我们要查提供某一个产品的供应商的全部信息,那就要先到表2中把供应商的地址和联系人先查出来,然后再结合表1中对应产品的其他信息
这时我们一种方式是分步处理:
1,按照步骤来,首先在表1中查出对应产品的供应商
2.在表2中查出对应的供应商的地址和联系人信息
另外一种是,嵌套子查询,一步设置完查询
但是这两种方式,操作起来都不是太方便,在输入的时候可能要多输入一些条件和内容才能达到我们想要的结果.因此就有了联结的概念.
如最上面所说,联结有几种方式:内联结,自联结,自然联结,外联结
内联结(INNER JOIN):内联结也可以称为等值联结.例如:
如以上两个表格中,每个订单包含订单编号,客户ID,订单日期,在Orders表中存储为一行,各订单的物品存储在相关的OrdersItems表中.Orders表不存储顾客的信息,只存储顾客ID.顾客的实际信息存储在Customers
表中.
现在,假如需要列出订购物品"RGAN01"的所有顾客,应该怎样检索?
步骤为下:
1.检索包含物品RGAN01的所有订单的编号.
2.检索具有前一步骤列出的订单编号的所有顾客 的ID
3.检索前一步骤返回的所有顾客ID的顾客信息
方法一:以上每步可以单独作为一个查询来执行.可以把一个SELECT 语句返回的结果用于另外一条SELECT语句的WHERE子句.
方法二:也可以使用子查询把3个查询组合成一条语句
方法三:直接使用内联结来关联两个表直接查询.
方法一实现:
2.方法二实现:
3.方法三实现:
上面是通过 WHERE 语句来实现的,这里面等同于 INNER JOIN...ON (INNER JOIN基本上只用于联结两个表,不太适合多个表联结).
INNER JOIN ...ON 的使用方式
2.自联结
例如:现在要给Jim Jones同一公司的所有顾客发送一封信件.这个查询要求首先找出Jim Jones工作的公司,然后找出在该公司工作的顾客.下面是实现代码:
通过customers表可以看出,cust_contact 里面对应的 Jim Jones 的公司是,Fun4All,然后筛选出 Fun4All 公司的其他联系人和客户ID
以上是通过子查询的方式实现的.
先对对比一下自联结方式实现:
此处要非常小心一定是要c2来进行过滤
待继续编辑...