1. 程式人生 > >mysql 關聯查詢技巧

mysql 關聯查詢技巧

.class 成交 log signed arc 通過 comment 性別 isa

廢話不多說,直接進入正題

#數據準備

班級表class:

CREATE TABLE `class` (
  `class_no` int(2) unsigned zerofill NOT NULL AUTO_INCREMENT COMMENT 班級編號,
  `class_name` varchar(30) CHARACTER SET utf8 NOT NULL COMMENT 班級名稱,
  PRIMARY KEY (`class_no`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
insert into class values(1, 培優班
); insert into class values(2, 普通班); insert into class values(3, 提升班);

學生表student:

CREATE TABLE `student` (
  `stu_no` int(2) unsigned zerofill NOT NULL AUTO_INCREMENT COMMENT 學員編號,
  `stu_name` varchar(30) CHARACTER SET utf8 NOT NULL COMMENT 學員姓名,
  `stu_sex` varchar(3) CHARACTER SET utf8 NOT
NULL COMMENT 學員性別, `stu_age` tinyint(2) unsigned zerofill DEFAULT NULL COMMENT 學員年代, `grade` double(5,2) unsigned zerofill DEFAULT NULL COMMENT 成績, `class_no` int(2) unsigned zerofill DEFAULT NULL COMMENT 所在班級編號, PRIMARY KEY (`stu_no`), KEY `class_no` (`class_no`) ) ENGINE=MyISAM AUTO_INCREMENT=
11 DEFAULT CHARSET=latin1; insert into student values(01, 李白, , 18, 60, 01); insert into student values(02, 杜甫, , 20, 76, 01); insert into student values(03, 張飛, , 32, 80, 02); insert into student values(04, 韓信, , 26, 98, 02); insert into student values(05, 了龍, , 27, 56, 02); insert into student values(06, 大喬, , 17, 88, 01); insert into student values(07, 小喬, , 16, 96, 01); insert into student values(08, 小喬, , 16, 90, 01); insert into student values(09, 關哥, , 32, 80, 02); insert into student values(10, 劉備, , 36, 98, null);

1: exists子查詢

如果子查詢有返回結果則為true,如果沒有返回值則為false

select * from student where exists(select * from student where grade = 80)

技術分享

比如not exists:

select * from student where not exists(select * from student where grade = 80);

以上結果返回空,因為 not exists 返回了 false

select * from student where exists (select * from class where class.class_no = student.class_no);

技術分享

上面的查詢可以看到,我們少了一條數據,第十條的clas_no 是null。。。所以這條數據是flase....而

class.class_no = student.class_no 為true的,就全部返回了

2: [union] 並合查詢

需求: 拿到01班級的最高成績 和 02班級的最低成績

我們一般會這樣

select max(grade) from student where class_no = 01;
select min(grade) from student where class_no = 02;

優化這個查詢我們可以這樣:

(select concat(1號班級最高成績:, max(grade)) 成績 from student where class_no = 01)
union
(select concat(2號班級最低成績:, min(grade)) 成績 from student where class_no = 02);

技術分享

這裏再說下union 和union all的區別:

union:

(select class_no, stu_name, stu_age from student where class_no = 1)
union
(select class_no, stu_name, stu_age from student where class_no = 2);

技術分享

union all:

(select class_no, stu_name, stu_age from student where class_no = 1)
union all
(select class_no, stu_name, stu_age from student where class_no = 2);

技術分享

通過以上兩個查詢,我們可以看到:union並合查詢它會自動的去重復的記錄, 如果不想要去掉重復的記錄則可以使用 union all;

我們加個排序:

(select class_no, stu_name, stu_age from student where class_no = 1)
union all
(select class_no, stu_name, stu_age from student where class_no = 2) order by stu_age desc;

技術分享

連接查詢的分類
1: 內連接
2: 外連接
3: 自然連接

1: inner join(內連接)
需求: 查詢出學員的學號, 姓名, 所在的班級名稱

select stu_no, stu_name, class_name from student  join class where `student`.class_no = `class`.class_no;

技術分享

以上sql等同於:

select stu_no, stu_name, class_name from student join class where `student`.class_no = `class`.class_no;
select stu_no,stu_name,class_name from student,class where student.class_no = class.class_no;

內連接的inner字符可以不用寫

2: cross join(交叉連接,迪卡爾集) 沒有條件的內連接
例: select * from student cross join class;
例: select * from student inner join class;
例: select * from student cross join class where `student`.class_no = `class`.class_no;
ps: cross join 與 inner join 在使用上沒有區分,只是在mysql中把cross join定義成交叉連接而已

就寫到這把。。其他的連接方式也簡單,資料也很多啦。。。

mysql 關聯查詢技巧