JOIN子句的用法
JOIN是很好用的一個SELECT查詢的子句,雖然有了它以后你的查詢語句變得非常的長,寫錯的概率也增大了;可是四分之一柱香以后,你就會徹底的愛上它,因為我決定把它的優點全部展示給你!
為了便于讀者接受,我們還是先來建一個數據庫吧。
#貨物表
create table goods (
id int auto_increment,
code varchar(10) not null,
name varchar(20),
spec varchar(40),
grade varchar(10),
PRimary key(id) );
#業務員表
create table staff (
id int auto_increment,
name varchar(20),
depart int not null,
primary key(id) );
#部門表
create table depart (
id int auto_increment,
name varchar(20),
primary key(id) );
#客戶表
create table customer (
id int auto_increment,
name varchar(60) not null,
association varchar(20),
tel varchar(30),
fax varchar(30),
addr varchar(80),
postcode varchar(10),
email varchar(40),
primary key(id) );
#銷售記錄表
create table sales (
id int auto_increment,
inputime datetime not null,
staff int not null,
customer int not null,
good_code varchar(10) not null,
amount decimal(10,2) not null default 0.00,
price decimal(8,2) not null default 0.00,
memo text,
primary key(id) );
#插入數據
insert into goods (code,name,spec,grade)
values ('A0001','顯示器','PHILipS 105B','優');
insert into goods (code,name,spec,grade)
values ('A0002','顯示器','PHILIPS 107B','優');
insert into depart (name)
values ('業務一部');
insert into depart (name)
values ('業務二部');
insert into depart (name)
values ('業務三部');
insert into staff (name,depart)
values ('王老五',2);
insert into staff (name,depart)
values ('張三',3);
insert into staff (name,depart)
values ('李四',1);
insert into staff (name,depart)
values ('趙二楞',3);
insert into customer (name,association,tel,fax,email)
values ('丁胖子電腦公司','丁胖子','12345678','12345679','fatding@fat.org');
insert into sales (inputime,staff,customer,good_code,amount,price)
values (now(),2,1,'A0001',10,1200.00);
insert into sales (inputime,staff,customer,good_code,amount,price)
values (now(),6,2,'A0001',10,1200.00);
想必不用我一個一個字段地解釋,其中用的字段名字都是很普通的啊。我們這樣做的目的是為了在龐大的銷售記錄表中不要直接記錄貨物的名稱、規格、客戶的名稱、業務員的姓名等重復性的東西——那樣太浪費。我們把所有可能牽扯到的貨物、業務員、客戶等等分別做為一個表,他們在各自的表中有一個唯一標識的編號,而在銷售記錄表中,就只填寫這個編號。
在查看銷售記錄的時候,要把其中的貨物代碼轉換成它對應的貨物名稱和規格、等級等等;還有把客戶的編號轉換成客戶的名稱;業務員的編號換成他的名字……。我們就用JOIN子句,注意看下面這條查詢:
SELECT sales.id,sales.inputime,sales.amount,sales.price,sales.memo,
staff.name as staff,depart.name as depart,customer.name as customer,
goods.name as good_name,goods.spec as good_spec,goods.grade as good_grade
FROM sales INNER JOIN staff ON staff.id=sales.staff
INNER JOIN depart ON depart.id=staff.depart
INNER JOIN customer ON customer.id=sales.customer
INNER JOIN goods ON goods.code=sales.good_code
ORDER BY inputime desc
注意這是不是幾條,是一條SELECT語句!!嗯,比較長。由于查詢的結果也比較長,寫出來大家也不一定能看清楚,所以就請自己試一下吧。查詢的結果,各個字段對應的分別是:
inputime 錄入的時間
amount 銷售數量
price 價格
memo 備注
staff 業務員姓名
depart 業務員所屬部門
customer 客戶名稱
good_name 貨物名稱
good_spec 貨物規格
good_grade 貨物等級
當sales表中的staff字段的值,在staff表中找不到對應的業務員記錄時,這可能是兩鐘原因造成的:一為誤刪除了這個業務員,二為這一條銷售記錄填入sales表時出現了失誤。在這種情況下,使用上面的一條查詢就不能將這一條記錄取出。剛才我建的數據庫sales表中故意留了一條業務員ID是6的記錄——業務員表中沒有ID是6的!所以按照上面的那條查詢,就沒有查詢到這條記錄。如果要避免這種情況發生,可以使用“左連接”:無論匹配與否,取出左側的表中的所有記錄,不能匹配的右側的表的記錄一律為NULL。上述的查詢應改為:
SELECT sales.id,sales.inputime,sales.amount,sales.price,sales.memo,
staff.name as staff,depart.name as depart,customer.name as customer,
goods.name as good_name,goods.spec as good_spec,goods.grade as good_grade
FROM sales LEFT JOIN staff ON staff.id=sales.staff
LEFT JOIN depart ON depart.id=staff.depart
LEFT JOIN customer ON customer.id=sales.customer
LEFT JOIN goods ON goods.code=sales.good_code
ORDER BY inputime desc
再用這個語句查詢一次,是不是比剛才查到的多了一條業務員和所屬部門是NULL的記錄?業務員被誤刪是應該絕對禁止的,填寫sales表時的失誤也應該避免。但是一旦發生了,就應該不使它影響到整個銷售記錄數據的正常存取。所以用“左連接”是必要的。
時間倉促,草草成稿;如有不確,務請指正。