數據庫多表查詢,一對一關系,一對多關系,多對多關系



數據庫day03

	
	1. 表的操作:
		增:
			create table 表名(
				字段名  字段類型  [字段的約束],
				字段名  字段類型  [字段的約束],
				....... 
			)charset=utf8;
			
			字段類型:
				
				數字:
					整數
						tinyint 
						smallint
						int  (***************************)
						mediumint
						bigint
						
						區別:
							取值的范圍不一樣
							加上unsigned, 代表只能取整數
							
					浮點數
						
						float
						double
						decimal(10,5)
						
						如果,保存的是工資類型的話,我們推薦使用decimal
				
				字符串類型:
					char()
					
					varchar()
					
					區別:	
						1.char(4) ‘ab  ’----》占4個字節,剩余的不足的字節使用空字節來補充, 身份證, 

手機號, md5密碼
						2.varchar(4) ‘ab’ ----》 占3個字節,其中有兩個字節是自己本身的大小, 還有一個

是記錄字節大小的
				
				時間日期類型:
					datetime(*******************8**)
					年月日 時分秒
				
				枚舉:
					gender enum('male', 'female') default 'male'
					

			列的約束 (可選的參數):
				not null :不能為null
				auto_increment: 自增 
				primary key:主鍵索引 加快查詢速度
				default 默認值
				
		刪除:
			drop table 表名;
		
		修改:
			alter table 表名 add 字段名  字段類型  [字段的約束];
			
			alter table 表名 add 字段名  字段類型  [字段的約束] first;
			
			alter table 表名 add 字段名  字段類型  [字段的約束] after 字段名;
			
			alter table 表名 drop 字段名;
			
			alter table 表名 modify 字段名 字段類型  [字段的約束] ;
			
			alter table 表名 change 舊的字段 新的字段 字段類型  [字段的約束] ;
			
		查:
			show tables;
			
	2. 操作數據行:
		
		增
			insert into 表名 (列1, 列2) values (值1, 值2), (值1, 值2);

		刪
			delete from 表名;
			delete from 表名 where id = 10;
			delete from 表名 where id > 10;
			delete from 表名 where id < 10;
			delete from 表名 where id <= 10;
			delete from 表名 where id >= 10;
			delete from 表名 where id != 10;
			delete from 表名 where id <> 10;
			delete from 表名 where id = 10 and name='zekai';

			truncate 表名;
			
		改
			update 表名 set name='zekai', age=12;
			update 表名 set name='zekai', age=15 where age=12 and num=10;
			
		查
			
			select * from 表名; 
			select 列名1, 列名2,... from 表名;
			
			select * from 表名 where id = 10;
			select * from 表名 where id != 10;
			select * from 表名 where id > 10;
			select * from 表名 where id < 10;
			select * from 表名 where id >= 10;
			select * from 表名 where id <= 10;
			
			between...and...
				select * from 表名 where  id  between 30 and 40;
			
			select distinct name from t66;
			
			select * from t66 where id in (23,34,11);
			
			
			



今日內容:
	
	0. null和notnull:
		使用null的時候:
			
			create table t8(
				
				id int auto_increment primary key,
				name varchar(32),
				email varchar(32)
			)charset=utf8;
			
			insert into t8 (email) values ('xxxx');
			
			mysql> insert into t8 (email) values ('xxxx');
			Query OK, 1 row affected (0.05 sec)

			mysql> select * from t8;
			+----+------+-------+
			| id | name | email |
			+----+------+-------+
			|  1 | NULL | xxxx  |
			+----+------+-------+
			1 row in set (0.00 sec)

			mysql> select * from t8 where name='';
			Empty set (0.00 sec)

			mysql> select * from t8 where name is null;
			+----+------+-------+
			| id | name | email |
			+----+------+-------+
			|  1 | NULL | xxxx  |
			+----+------+-------+
			1 row in set (0.01 sec)
				

		使用 notnull的時候:
			create table t9(
				
				id int auto_increment primary key,
				name varchar(32) not null default '',
				email varchar(32) not null default ''
			)charset=utf8;
			
			insert into t9 (email) values ('xxxx');
			
			mysql> insert into t9 (email) values ('xxxx');
			Query OK, 1 row affected (0.03 sec)

			mysql> select * from t9;
			+----+------+-------+
			| id | name | email |
			+----+------+-------+
			|  1 |      | xxxx  |
			+----+------+-------+
			1 row in set (0.00 sec)

			mysql> select * from t9 where name='';
			+----+------+-------+
			| id | name | email |
			+----+------+-------+
			|  1 |      | xxxx  |
			+----+------+-------+
			1 row in set (0.00 sec)

	
	1.單表操作 (******************)
		分組:
				
			- group by
				a、分組指的是:將所有記錄按照某個相同字段進行歸類,比如針對員工信息表的職位分組,或者按照性別

進行分組等
				用法:
					select 聚合函數, 選取的字段 from  employee group by 分組的字段;
					
					group by : 是分組的關鍵詞
					group by 必須和 聚合函數(count) 出現
					
					where 條件語句和group by分組語句的先后順序:
						where > group by > having(*********)
					
				例子:
				
					1. 以性別為例, 進行分組, 統計一下男生和女生的人數是多少個:
				
						select count(id), gender from  employee group by gender;
						+-----------+--------+
						| count(id) | gender |
						+-----------+--------+
						|        10 | male   |
						|         8 | female |
						+-----------+--------+
						2 rows in set (0.00 sec)
					
						mysql> select gender, count(id) as total from  employee group by gender;
						+--------+-------+
						| gender | total |
						+--------+-------+
						| male   |    10 |
						| female |     8 |
						+--------+-------+
						2 rows in set (0.00 sec)
					
					2. 對部門進行分組, 求出每個部門年齡最大的那個人?
						mysql> select depart_id,max(age) from employee group by depart_id;
						+-----------+----------+
						| depart_id | max(age) |
						+-----------+----------+
						|         1 |       81 |
						|         2 |       48 |
						|         3 |       28 |
						+-----------+----------+
						3 rows in set (0.01 sec)
					
					3. min : 求最小的
					
					4. sum : 求和
					5. count : 計數 數量
					
					count 和 sum的區別:
					mysql> select depart_id,count(age) from employee group by depart_id;
					+-----------+------------+
					| depart_id | count(age) |
					+-----------+------------+
					|         1 |          8 |
					|         2 |          5 |
					|         3 |          5 |
					+-----------+------------+
					3 rows in set (0.00 sec)

					mysql> select depart_id,sum(age) from employee group by depart_id;
					+-----------+----------+
					| depart_id | sum(age) |
					+-----------+----------+
					|         1 |      362 |
					|         2 |      150 |
					|         3 |      100 |
					+-----------+----------+
					3 rows in set (0.03 sec)
					
					6. avg : 平均數
				
					
			- having
			
				表示對group by 之后的數據, 進行再一次的二次篩選
				
				mysql> select depart_id,avg(age) from employee group by depart_id ;
				+-----------+----------+
				| depart_id | avg(age) |
				+-----------+----------+
				|         1 |  45.2500 |
				|         2 |  30.0000 |
				|         3 |  20.0000 |
				+-----------+----------+
				3 rows in set (0.00 sec)

				mysql> select depart_id,avg(age) from employee group by depart_id having avg(age) > 35;
				+-----------+----------+
				| depart_id | avg(age) |
				+-----------+----------+
				|         1 |  45.2500 |
				+-----------+----------+
				1 row in set (0.00 sec)

				mysql> select depart_id,avg(age) as pj from employee group by depart_id having pj > 35;
				+-----------+---------+
				| depart_id | pj      |
				+-----------+---------+
				|         1 | 45.2500 |
				+-----------+---------+
				1 row in set (0.00 sec)

				where 條件語句和groupby分組語句的先后順序:
					
					where > group by > having(*********)
				
		
		升序 降序
		
			order by
			
				order by 字段名 asc (升序) desc(降序)
			
				如果對多個字段進行排序,
				比如:
					age desc, id asc;
					表示: 先對age進行降序, 如果age有相同的行, 則對id進行升序
				
				 select * from employee order by age desc, id desc;
				+----+------------+--------+-----+------------+----------------------------+--------------

+------------+--------+-----------+
				| id | name       | gender | age | hire_date  | post                       | post_comment | 

salary     | office | depart_id |
				+----+------------+--------+-----+------------+----------------------------+--------------

+------------+--------+-----------+
				|  3 | wupeiqi    | male   |  81 | 2013-03-05 | teacher                    | NULL         |    

8300.00 |    401 |         1 |
				|  2 | alex       | male   |  78 | 2015-03-02 | teacher                    | NULL         | 

1000000.31 |    401 |         1 |
				|  4 | yuanhao    | male   |  73 | 2014-07-01 | teacher                    | NULL         |    

3500.00 |    401 |         1 |
				|  9 | 歪歪       | female |  48 | 2015-03-11 | sale                       | NULL         |    

3000.13 |    402 |         2 |
				|  8 | 成龍       | male   |  48 | 2010-11-11 | teacher                    | NULL         |   

10000.00 |    401 |         1 |
				| 10 | 丫丫       | female |  38 | 2010-11-01 | sale                       | NULL         |    

2000.35 |    402 |         2 |
				| 14 | 張野       | male   |  28 | 2016-03-11 | operation                  | NULL         |   

10000.13 |    403 |         3 |
				| 13 | 格格       | female |  28 | 2017-01-27 | sale                       | NULL         |    

4000.33 |    402 |         2 |
				|  5 | liwenzhou  | male   |  28 | 2012-11-01 | teacher                    | NULL         |    

2100.00 |    401 |         1 |
				| 18 | 程咬鐵     | female |  18 | 2014-05-12 | operation                  | NULL         |   

17000.00 |    403 |         3 |
				| 17 | 程咬銅     | male   |  18 | 2015-04-11 | operation                  | NULL         |   

18000.00 |    403 |         3 |
				| 16 | 程咬銀     | female |  18 | 2013-03-11 | operation                  | NULL         |   

19000.00 |    403 |         3 |
				| 15 | 程咬金     | male   |  18 | 1997-03-12 | operation                  | NULL         |   

20000.00 |    403 |         3 |
				| 12 | 星星       | female |  18 | 2016-05-13 | sale                       | NULL         |    

3000.29 |    402 |         2 |
				| 11 | 丁丁       | female |  18 | 2011-03-12 | sale                       | NULL         |    

1000.37 |    402 |         2 |
				|  7 | jinxin     | male   |  18 | 1900-03-01 | teacher                    | NULL         |   

30000.00 |    401 |         1 |
				|  6 | jingliyang | female |  18 | 2011-02-11 | teacher                    | NULL         |    

9000.00 |    401 |         1 |
				|  1 | egon       | male   |  18 | 2017-03-01 | 老男孩駐沙河辦事處外交大使 | NULL         |    

7300.33 |    401 |         1 |
				+----+------------+--------+-----+------------+----------------------------+--------------

+------------+--------+-----------+
		
		
		limit
			分頁
			limit offset, size
			
			offset: 行數據索引,按照下表索引開始取值
			size: 取多少條數據
			
			mysql> select * from employee limit 0,10;
				+----+------------+--------+-----+------------+----------------------------+--------------

+------------+--------+-----------+
				| id | name       | gender | age | hire_date  | post                       | post_comment | 

salary     | office | depart_id |
				+----+------------+--------+-----+------------+----------------------------+--------------

+------------+--------+-----------+
				|  1 | egon       | male   |  18 | 2017-03-01 | 老男孩駐沙河辦事處外交大使 | NULL         |    

7300.33 |    401 |         1 |
				|  2 | alex       | male   |  78 | 2015-03-02 | teacher                    | NULL         | 

1000000.31 |    401 |         1 |
				|  3 | wupeiqi    | male   |  81 | 2013-03-05 | teacher                    | NULL         |    

8300.00 |    401 |         1 |
				|  4 | yuanhao    | male   |  73 | 2014-07-01 | teacher                    | NULL         |    

3500.00 |    401 |         1 |
				|  5 | liwenzhou  | male   |  28 | 2012-11-01 | teacher                    | NULL         |    

2100.00 |    401 |         1 |
				|  6 | jingliyang | female |  18 | 2011-02-11 | teacher                    | NULL         |    

9000.00 |    401 |         1 |
				|  7 | jinxin     | male   |  18 | 1900-03-01 | teacher                    | NULL         |   

30000.00 |    401 |         1 |
				|  8 | 成龍       | male   |  48 | 2010-11-11 | teacher                    | NULL         |   

10000.00 |    401 |         1 |
				|  9 | 歪歪       | female |  48 | 2015-03-11 | sale                       | NULL         |    

3000.13 |    402 |         2 |
				| 10 | 丫丫       | female |  38 | 2010-11-01 | sale                       | NULL         |    

2000.35 |    402 |         2 |
				+----+------------+--------+-----+------------+----------------------------+--------------

+------------+--------+-----------+
				10 rows in set (0.00 sec)
			在取值的過程中,如果不夠10條數據,那么會顯示剩下的所有,所以只能顯示到11--18的值。

			mysql> select * from employee limit 10,10;
				+----+--------+--------+-----+------------+-----------+--------------+----------+--------

+-----------+
				| id | name   | gender | age | hire_date  | post      | post_comment | salary   | office | 

depart_id |
				+----+--------+--------+-----+------------+-----------+--------------+----------+--------

+-----------+
				| 11 | 丁丁   | female |  18 | 2011-03-12 | sale      | NULL         |  1000.37 |    402 |     

    2 |
				| 12 | 星星   | female |  18 | 2016-05-13 | sale      | NULL         |  3000.29 |    402 |     

    2 |
				| 13 | 格格   | female |  28 | 2017-01-27 | sale      | NULL         |  4000.33 |    402 |     

    2 |
				| 14 | 張野   | male   |  28 | 2016-03-11 | operation | NULL         | 10000.13 |    403 |     

    3 |
				| 15 | 程咬金 | male   |  18 | 1997-03-12 | operation | NULL         | 20000.00 |    403 |     

    3 |
				| 16 | 程咬銀 | female |  18 | 2013-03-11 | operation | NULL         | 19000.00 |    403 |     

    3 |
				| 17 | 程咬銅 | male   |  18 | 2015-04-11 | operation | NULL         | 18000.00 |    403 |     

    3 |
				| 18 | 程咬鐵 | female |  18 | 2014-05-12 | operation | NULL         | 17000.00 |    403 |     

    3 |
				+----+--------+--------+-----+------------+-----------+--------------+----------+--------

+-----------+
				8 rows in set (0.00 sec)

				
				
		總結:(***************************)
			使用的順序:
				
				select * from 表名  where 條件 group by 條件 having 條件 order by 條件 limit 條件;
			條件查詢的優先級別排列:
				
				where > group by > having > order by > limit 
			
			
				

	2. 多表操作 (**************************)
	
		外鍵
		
			使用的原因:
				a. 減少占用的空間
				b. 只需要修改department表中一次, 其余的表中的數據就會相應的修改
				
			一對多:
			
				使用方法:
					constraint 外鍵名 foreign key (被約束的字段) references 約束的表(約束的字段)
				
				create table department(
					id int auto_increment primary key,
					name varchar(32) not null default ''
				)charset utf8;
				
				insert into department (name) values ('研發部');
				insert into department (name) values ('運維部');
				insert into department (name) values ('前台部');
				insert into department (name) values ('小賣部');
				
				create table userinfo (
					id int auto_increment primary key,
					name varchar(32) not null default '',
					depart_id int not null default 1,
					
					constraint fk_user_depart foreign key (depart_id) references department(id)
					#constraint fk_user_depart foreign key (depart_id) references department(id),
					#constraint fk_user_depart foreign key (depart_id) references department(id),
					
				)charset utf8;
				
				insert into userinfo (name, depart_id) values ('zekai', 1);
				insert into userinfo (name, depart_id) values ('xxx', 2);
				insert into userinfo (name, depart_id) values ('zekai1', 3);
				insert into userinfo (name, depart_id) values ('zekai2', 4);
				insert into userinfo (name, depart_id) values ('zekai3', 1);
				insert into userinfo (name, depart_id) values ('zekai4', 2);

				
			
			多對多:
				create table boy (
					id int auto_increment primary key,
					bname varchar(32) not null default ''
				)charset utf8;
				
				insert into boy (bname) values ('zhangsan'),('lisi'),('zhaoliu');
				
				create table girl (
					id int auto_increment primary key,
					gname varchar(32) not null default ''
				)charset utf8;

				insert into girl (gname) values ('cuihua'),('gangdan'),('jianguo');
				
				create table boy2girl (
					id int auto_increment primary key,
					bid int not null default 1,
					gid int not null default 1,
					
					constraint fk_boy2girl_boy foreign key (bid) references boy(id),
					constraint fk_boy2girl_girl foreign key (gid) references girl(id)
				)charset utf8;
				
				insert into boy2girl (bid, gid) values (1,1),(1,2),(2,3),(3,3),(2,2);
				
				select * from boy left join  boy2girl on boy.id = boy2girl.bid


				mysql>select * from priv left join user on priv.uid=user.id;
				
					+----+--------+-----+------+----------+
					| id | salary | uid | id   | name     |
					+----+--------+-----+------+----------+
					|  1 |   2000 |   1 |    1 | zhangsan |
					|  2 |   2800 |   2 |    2 | zekai    |
					|  3 |   3000 |   3 |    3 | kkk      |
					+----+--------+-----+------+----------+
					3 rows in set (0.00 sec)


				select * from boy left join  boy2girl on boy.id = boy2girl.bid left join girl on 

girl.id=boy2girl.gid;
				
				mysql> select * from boy left join  boy2girl on boy.id = boy2girl.bid left join girl on 

girl.id=boy2girl.gid;
				+----+----------+------+------+------+------+---------+
				| id | bname    | id   | bid  | gid  | id   | gname   |
				+----+----------+------+------+------+------+---------+
				|  1 | zhangsan |    1 |    1 |    1 |    1 | cuihua  |
				|  1 | zhangsan |    2 |    1 |    2 |    2 | gangdan |
				|  2 | lisi     |    5 |    2 |    2 |    2 | gangdan |
				|  2 | lisi     |    3 |    2 |    3 |    3 | jianguo |
				|  3 | zhaoliu  |    4 |    3 |    3 |    3 | jianguo |
				+----+----------+------+------+------+------+---------+
				5 rows in set (0.00 sec)

				mysql> select bname, gname from boy left join  boy2girl on boy.id = boy2girl.bid left join 

girl on girl.id=boy2girl.gid;
				+----------+---------+
				| bname    | gname   |
				+----------+---------+
				| zhangsan | cuihua  |
				| zhangsan | gangdan |
				| lisi     | gangdan |
				| lisi     | jianguo |
				| zhaoliu  | jianguo |
				+----------+---------+
				5 rows in set (0.00 sec)
				
				mysql> select bname, gname from boy left join  boy2girl on boy.id = boy2girl.bid left join 

girl on girl.id=boy2girl.gid where bname='zhangsan';
				+----------+---------+
				| bname    | gname   |
				+----------+---------+
				| zhangsan | cuihua  |
				| zhangsan | gangdan |
				+----------+---------+
				2 rows in set (0.02 sec)
			
			
			一對一:
				
				user :
					id   name  age  
					1    zekai  18   
					2    zhangsan 23  
					3    xxxx   19   
				
				由於salary是比較敏感的字段,因此我們需要將此字段單獨拆出來, 變成一張獨立的表
				
				private:
					
					id  salary   uid  (外鍵 + unique)
					1    5000     1
					2    6000     2
					3    3000     3
					
					
				create table user (
					id int auto_increment primary key,
					name varchar(32) not null default ''
				)charset=utf8;
				
				insert into user (name) values ('zhangsan'),('zekai'),('kkk');
				
				
				create table priv(
					id int auto_increment primary key,
					salary int not null default 0,
					uid int not null default 1,
					
					constraint fk_priv_user foreign key (uid) references user(id),
					unique(uid)
				)charset=utf8;
				
				insert into priv (salary, uid) values (2000, 1);
				insert into priv (salary, uid) values (2800, 2);
				insert into priv (salary, uid) values (3000, 3);
				
				insert into priv (salary, uid) values (6000, 1);
				ERROR 1062 (23000): Duplicate entry '1' for key 'uid'
					
					
					
		多表聯查:
			
			mysql> select * from department;
			+----+--------+
			| id | name   |
			+----+--------+
			|  1 | 研發部 |
			|  2 | 運維部 |
			|  3 | 前台部 |
			|  4 | 小賣部 |
			+----+--------+
			4 rows in set (0.07 sec)

			mysql> select * from userinfo;
			+----+--------+-----------+
			| id | name   | depart_id |
			+----+--------+-----------+
			|  1 | zekai  |         1 |
			|  2 | xxx    |         2 |
			|  3 | zekai1 |         3 |
			|  4 | zekai2 |         4 |
			|  5 | zekai3 |         1 |
			|  6 | zekai4 |         2 |
			+----+--------+-----------+
			6 rows in set (0.00 sec)

			left join .... on這個是左連接查詢的SQL命令語法格式。
				
				select * from userinfo left join department on userinfo.depart_id = department.id
				
				
				mysql> select name  from userinfo left join department on depart_id = department.id;
				ERROR 1052 (23000): Column 'name' in field list is ambiguous
				
				mysql> select userinfo.name as uname, department.name as dname  from userinfo left join 

department on depart_id = department.id;
				+--------+--------+
				| uname  | dname  |
				+--------+--------+
				| zekai  | 研發部 |
				| zekai3 | 研發部 |
				| xxx    | 運維部 |
				| zekai4 | 運維部 |
				| zekai1 | 前台部 |
				| zekai2 | 小賣部 |
				+--------+--------+
				6 rows in set (0.00 sec)
				
				
				
				
				right join ... on這個是右連接查詢的SQL命令語法格式。
				
				mysql> insert into department (name) values ('財務部');
				Query OK, 1 row affected (0.04 sec)

				mysql>
				mysql> select * from department;                     );
				+----+--------+
				| id | name   |
				+----+--------+
				|  1 | 研發部 |
				|  2 | 運維部 |
				|  3 | 前台部 |
				|  4 | 小賣部 |
				|  5 | 財務部 |
				+----+--------+
				5 rows in set (0.00 sec)

				mysql> select * from userinfo;
				+----+--------+-----------+
				| id | name   | depart_id |
				+----+--------+-----------+
				|  1 | zekai  |         1 |
				|  2 | xxx    |         2 |
				|  3 | zekai1 |         3 |
				|  4 | zekai2 |         4 |
				|  5 | zekai3 |         1 |
				|  6 | zekai4 |         2 |
				+----+--------+-----------+
				6 rows in set (0.00 sec)

				mysql> select userinfo.name as uname, department.name as dname  from userinfo left join 

department on depart_id = department.id;
				+--------+--------+
				| uname  | dname  |
				+--------+--------+
				| zekai  | 研發部 |
				| zekai3 | 研發部 |
				| xxx    | 運維部 |
				| zekai4 | 運維部 |
				| zekai1 | 前台部 |
				| zekai2 | 小賣部 |
				+--------+--------+
				6 rows in set (0.00 sec)

				mysql> select userinfo.name as uname, department.name as dname  from userinfo right join 

department on depart_id = department.id;
				+--------+--------+
				| uname  | dname  |
				+--------+--------+
				| zekai  | 研發部 |
				| zekai3 | 研發部 |
				| xxx    | 運維部 |
				| zekai4 | 運維部 |
				| zekai1 | 前台部 |
				| zekai2 | 小賣部 |
				| NULL   | 財務部 |
				+--------+--------+
				7 rows in set (0.00 sec)
				
				
				
			
			
			inner join.....on查詢
			
				mysql> select * from department inner join userinfo on department.id=userinfo.depart_id;
				+----+--------+----+--------+-----------+
				| id | name   | id | name   | depart_id |
				+----+--------+----+--------+-----------+
				|  1 | 研發部 |  1 | zekai  |         1 |
				|  1 | 研發部 |  5 | zekai3 |         1 |
				|  2 | 運維部 |  2 | xxx    |         2 |
				|  2 | 運維部 |  6 | zekai4 |         2 |
				|  3 | 前台部 |  3 | zekai1 |         3 |
				|  4 | 小賣部 |  4 | zekai2 |         4 |
				+----+--------+----+--------+-----------+
				6 rows in set (0.00 sec)
			
			
			

	
		
		
		
		
		
		

		
		
	
	






免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM