SQL语句中的注释:
-- 单行注释
/* .... */ 多行注释
每个sql语句结束需要写;来结束
需要在某个库中添加表需要use这个库
SQL DML 和DDL
DML 数据操作语言
DDL 数据定义语言
DML : 对数据库表的操作
CREATE TABLE 创建新表
1 --创建一个员工表employee
2
3 create tableemployee(4 id int primary keyauto_increment ,5 name varchar(20),6 gender bit default 1, --gender char(1) default 1 ----- 或者 TINYINT(1)
7 birthday date,8 job varchar(20),9 salary double(4,2) unsigned,10 resume text --注意,这里作为最后一个字段不加逗号
11 );12
13 /*约束:14 primary key (非空且唯一) :能够唯一区分出当前记录的字段称为主键!15 unique16 not null17 auto_increment :用于主键字段,主键字段必须是数字类型18 */
ALTER TABLE 变更数据库表
DESC tab_name 查看表信息
SHOW COLUMNS FROM tab_name 查看表结构
SHOW TABLES 查看当前数据库中所有的表
SHOW CREATE TABLE tab_name 查看当前数据库表建表语句
修改表结构:
1 --(1)增加列(字段)
2 alter table tab_name add [column]列名 类型[完整性约束条件][first|after 字段名];3 alter table user add addr varchar(20) not null unique first/after username;4 #添加多个字段5 alter tableusers26 add addr varchar(20),7 add age intfirst,8 add birth varchar(20) after name;9
10 --(2)修改一列类型
11 alter table tab_name modify 列名 类型 [完整性约束条件][first|after 字段名];12 alter table users2 modify age tinyint default 20;13 alter table users2 modify age intafter id;14
15 --(3)修改列名
16 alter table tab_name change [column] 列名 新列名 类型 [完整性约束条件][first|after 字段名];17 alter table users2 change age Age int default 28first;18
19 --(4)删除一列
20 alter table tab_name drop [column]列名;21 --思考:删除多列呢?删一个填一个呢?
22 alter tableusers223 add salary float(6,2) unsigned not nullafter name,24 dropaddr;25
26 --(5)修改表名
27 rename table 表名 to新表名;28
29 --(6)修该表所用的字符集
30 alter table student character set utf8;
DROP TABLE tab_name 删除表
DELETE 从数据库表中删除数据
INSERT INTO 向数据库表中插入数据
INSERT [INTO] tab_name(field1,filed2) values(value1,value2),(value1,value2); 插入多条记录
INSERT INTO employee_new SET id=12,name="alvin3";#出入一条记录的另一种写法。
UPDATE 更新数据库表数据
UPDATE tab_name SET field=value,filed2=value2....[where];
/*UPDATE语法可以用新值更新原有表行中的各列。
SET子句指示要修改哪些列和要给予哪些值。
WHERE子句指定应更新哪些行。如没有WHERE子句,则更新所有的行。*/
UPDATE employee_new SET salary=salary+4000 WHERE name='yuan';--- 将yuan的薪水在原有基础上增加1000元。
DELETE FROM tab_name [WHERE...];/*如果不跟where语句则删除整张表中的数据
delete只能用来删除一行记录
delete语句只能删除表中的内容,不能删除表本身,想要删除表,用drop
TRUNCATE TABLE也可以删除表中的所有数据,词语句首先摧毁表,再新建表。
此种方式删除的数据不能在事务中恢复。*/
DELETE FROM employee_new WHERE name="alex";--删除表中名为"alex"的记录。
DELETE FROMemployee_new;--删除表中所有的记录
TRUNCATE TABLEemp_new;--使用truncate删除表中记录
SELECT 查询数据库表数据
1 SELECT *|field1,filed2 ... FROMtab_name2 WHERE条件3 GROUP BYfield 组4 HAVING筛选5 ORDER BYfield6 LIMIT 限制条数7 --(1)select [distinct] *|field1,field2,...... from tab_name
8 --其中from指定从哪张表筛选,*表示查找所有列,也可以指定一个列
9 --表明确指定要查找的列,distinct用来剔除重复行。
10
11 --查询表中所有学生的信息。
12 select * fromExamResult;13 --查询表中所有学生的姓名和对应的英语成绩。
14 select name,JS fromExamResult;15 --过滤表中重复数据。
16 select distinct JS ,name fromExamResult;17
18 --(2)select 也可以使用表达式,并且可以使用: 字段 as 别名或者:字段 别名
19
20 --在所有学生分数上加10分特长分显示。
21
22 select name,JS+10,Django+10,OpenStack+10 fromExamResult;23 --统计每个学生的总分。
24 select name,JS+Django+OpenStack fromExamResult;25 --使用别名表示学生总分。
26 select name as 姓名,JS+Django+OpenStack as 总成绩 fromExamResult;27 select name,JS+Django+OpenStack 总成绩 fromExamResult;28
29 select name JS from ExamResult; --what will happen?---->记得加逗号
增加比较运算符
--查询姓名为XXX的学生成绩
select * from ExamResult where name='yuan';--查询英语成绩大于90分的同学
select id,name,JS from ExamResult where JS>90;--查询总分大于200分的所有同学
select name,JS+Django+OpenStack as 总成绩 fromExamResultwhere JS+Django+OpenStack>200;--where字句中可以使用:
--比较运算符:
> < >= <= <> !=
between 80 and 100值在10到20之间in(80,90,100) 值是10或20或30like 'yuan%'
/*pattern可以是%或者_,
如果是%则表示任意多字符,此例如唐僧,唐国强
如果是_则表示一个字符唐_,只有唐僧符合。两个_则表示两个字符:__*/
--逻辑运算符
在多个条件直接可以使用逻辑运算符 and or not
ORDER BY 排序
指定排序的列,排序的列即可是表中的列名,也可以是select 语句后指定的别名。
--select *|field1,field2... from tab_name order by field [Asc|Desc]
--Asc 升序、Desc 降序,其中asc为默认值 ORDER BY 子句应位于SELECT语句的结尾。
--练习:
--对JS成绩排序后输出。
select * from ExamResult order byJS;--对总分排序按从高到低的顺序输出
select name ,(ifnull(JS,0)+ifnull(Django,0)+ifnull(Database,0))
总成绩from ExamResult order by 总成绩 desc;--对姓李的学生成绩排序输出
select name ,(ifnull(JS,0)+ifnull(Django,0)+ifnull(OpenStack,0))
总成绩from ExamResult where name like 'a%'
order by 总成绩 desc;
GROUP BY 分组查询
示例:
1 CREATE TABLEorder_menu(2 id INT PRIMARY KEYauto_increment,3 product_name VARCHAR (20),4 price FLOAT(6,2),5 born_date DATE,6 class VARCHAR (20)7 );8
9
10 INSERT INTO order_menu (product_name,price,born_date,class) VALUES
11 ("苹果",20,20170612,"水果"),12 ("香蕉",80,20170602,"水果"),13 ("水壶",120,20170612,"电器"),14 ("被罩",70,20170612,"床上用品"),15 ("音响",420,20170612,"电器"),16 ("床单",55,20170612,"床上用品"),17 ("草莓",34,20170612,"水果");18
19 --注意,按分组条件分组后每一组只会显示第一条记录
20
21 --group by字句,其后可以接多个列名,也可以跟having子句,对group by 的结果进行筛选。
22
23 --按位置字段筛选
24 select * from order_menu group by 5;25
26 --练习:对购物表按类名分组后显示每一组商品的价格总和
27 select class,SUM(price)from order_menu group byclass;28
29 --练习:对购物表按类名分组后显示每一组商品价格总和超过150的商品
30 select class,SUM(price)from order_menu group byclass31 HAVING SUM(price)>150;32
33
34
35 /*
36 having 和 where两者都可以对查询结果进行进一步的过滤,差别有:37 <1>where语句只能用在分组之前的筛选,having可以用在分组之后的筛选;38 <2>使用where语句的地方都可以用having进行替换39 <3>having中可以用聚合函数,where中就不行。40 */
41
42
43 --GROUP_CONCAT() 函数
44 SELECT id,GROUP_CONCAT(name),GROUP_CONCAT(JS) from ExamResult GROUP BY id;
聚合函数COUNT,SUM,AVG,MAX,MIN
1 --<1> 统计表中所有记录
2
3 --COUNT(列名):统计行的个数
4 --统计一个班级共有多少学生?先查出所有的学生,再用count包上
5 select count(*) fromExamResult;6 --统计JS成绩大于70的学生有多少个?
7 select count(JS) from ExamResult where JS>70;8 --统计总分大于280的人数有多少?
9 select count(name) fromExamResult10 where (ifnull(JS,0)+ifnull(Django,0)+ifnull(OpenStack,0))>280;11 --注意:count(*)统计所有行; count(字段)不统计null值.
12
13 --SUM(列名):统计满足条件的行的内容和
14 --统计一个班级JS总成绩?先查出所有的JS成绩,再用sum包上
15 select JS as JS总成绩 fromExamResult;16 select sum(JS) as JS总成绩 fromExamResult;17 --统计一个班级各科分别的总成绩
18 select sum(JS) asJS总成绩,19 sum(Django) asDjango总成绩,20 sum(OpenStack) as OpenStack fromExamResult;21
22 --统计一个班级各科的成绩总和
23 select sum(ifnull(JS,0)+ifnull(Django,0)+ifnull(Database,0))24 as 总成绩 fromExamResult;25 --统计一个班级JS成绩平均分
26 select sum(JS)/count(*) fromExamResult ;27 --注意:sum仅对数值起作用,否则会报错。
28
29 --AVG(列名):
30 --求一个班级JS平均分?先查出所有的JS分,然后用avg包上。
31 select avg(ifnull(JS,0)) fromExamResult;32 --求一个班级总分平均分
33 select avg((ifnull(JS,0)+ifnull(Django,0)+ifnull(Database,0)))34 fromExamResult ;35 --Max、Min
36 --求班级最高分和最低分(数值范围在统计中特别有用)
37 select Max((ifnull(JS,0)+ifnull(Django,0)+ifnull(OpenStack,0)))38 最高分 fromExamResult;39 select Min((ifnull(JS,0)+ifnull(Django,0)+ifnull(OpenStack,0)))40 最低分 fromExamResult;41 --求购物表中单价最高的商品名称及价格
42 ---SELECT id, MAX(price) FROM order_menu;--id和最高价商品是一个商品吗?
43
44 SELECT MAX(price) FROMorder_menu;45
46 --注意:null 和所有的数计算都是null,所以需要用ifnull将null转换为0!
47 ------ifnull(JS,0)
limit记录条数限制
1 SELECT * from ExamResult limit 1;2 SELECT * from ExamResult limit 2,5; --跳过前两条显示接下来的五条纪录
3 SELECT * from ExamResult limit 2,2;
正则表达式
1 SELECT * FROM employee WHERE emp_name REGEXP '^yu';2
3 SELECT * FROM employee WHERE emp_name REGEXP 'yun$';4
5 SELECT * FROM employee WHERE emp_name REGEXP 'm{2}';
DDL : 对数据库的操作
CREATE DATABASE 创建新数据库
CREATE DATABASE db_name CHARACTER SETutf8 创建库并定义字符编码
SHOW DATABASES 查看所有数据库
SHOW CREATE DATABASE db_name 查看数据库创建方式
ALTER DATABASE 修改数据库
ALTER DATABASE db_name CHARACTER SET utf8 修改数据库字符编码
DROP DATABASE 删除库
DROP DATABASE db_name 删除数据库
CREATE INDEX 创建索引
DROP INDEX 删除索引
DCL:数据库控制功能,设置或改变数据库用户或角色权限。
数据类型
char():指定个数的字符串,写20,必须20,19个就会报错
varchar:字符串
text:大文本字符串
float:浮点型,float(4,2) 4指最长位数,2指小数点2位,所以最多是99.99
bit :比特,比如性别,0为女1为男
上图,显示js大于85的
between关键字
like关键字 筛选a开头的
匹配a开头后面有3位的字段
and关键词
上图打印每个类的总价格
1 1、外键约束2 --- 每一个班主任会对应多个学生 , 而每个学生只能对应一个班主任
3
4 ----主表
5
6 CREATE TABLEClassCharger(7
8 id TINYINT PRIMARY KEYauto_increment,9 name VARCHAR (20),10 age INT,11 is_marriged boolean --show create table ClassCharger: tinyint(1)
12
13 );14
15 INSERT INTO ClassCharger (name,age,is_marriged) VALUES ("冰冰",12,0),16 ("丹丹",14,0),17 ("歪歪",22,0),18 ("姗姗",20,0),19 ("小雨",21,0);20
21
22 ----子表
23
24 CREATE TABLEStudent(25
26 id INT PRIMARY KEYauto_increment,27 name VARCHAR (20),28 charger_id TINYINT, --切记:作为外键一定要和关联主键的数据类型保持一致
29 --[ADD CONSTRAINT charger_fk_stu]FOREIGN KEY (charger_id) REFERENCES ClassCharger(id)
30
31 ) ENGINE=INNODB;32
33 INSERT INTO Student(name,charger_id) VALUES ("alvin1",2),34 ("alvin2",4),35 ("alvin3",1),36 ("alvin4",3),37 ("alvin5",1),38 ("alvin6",3),39 ("alvin7",2);40
41
42 DELETE FROM ClassCharger WHERE name="冰冰";43 INSERT student (name,charger_id) VALUES ("yuan",1);44 --删除居然成功,可是 alvin3显示还是有班主任id=1的冰冰的;
45
46 -----------增加外键和删除外键---------
47
48 ALTER TABLE student ADD CONSTRAINTabc49 FOREIGN KEY(charger_id)50 REFERENCESclasscharger(id);51
52
53 ALTER TABLE student DROP FOREIGN KEYabc;54
55 INNODB支持的on语句56 --外键约束对子表的含义: 如果在父表中找不到候选键,则不允许在子表上进行insert/update
57
58 --外键约束对父表的含义: 在父表上进行update/delete以更新或删除在子表中有一条或多条对
59 --应匹配行的候选键时,父表的行为取决于:在定义子表的外键时指定的
60 --on update/on delete子句
61
62
63 -----------------innodb支持的四种方式---------------------------------------
64
65 -----cascade方式 在父表上update/delete记录时,同步update/delete掉子表的匹配记录
66 -----外键的级联删除:如果父表中的记录被删除,则子表中对应的记录自动被删除--------
67
68 FOREIGN KEY (charger_id) REFERENCESClassCharger(id)69 ON DELETE CASCADE
70
71
72 ------set null方式 在父表上update/delete记录时,将子表上匹配记录的列设为null
73 --要注意子表的外键列不能为not null
74
75 FOREIGN KEY (charger_id) REFERENCESClassCharger(id)76 ON DELETE SET NULL
77
78
79 ------Restrict方式 :拒绝对父表进行删除更新操作(了解)
80
81 ------No action方式 在mysql中同Restrict,如果子表中有匹配的记录,则不允许对父表对应候选键
82 --进行update/delete操作(了解)
1 2、多表查询2 --准备两张表
3 --company.employee
4 --company.department
5
6 create tableemployee(7 emp_id int auto_increment primary key not null,8 emp_name varchar(50),9 age int,10 dept_id int
11 );12
13 insert into employee(emp_name,age,dept_id) values
14 ('A',19,200),15 ('B',26,201),16 ('C',30,201),17 ('D',24,202),18 ('E',20,200),19 ('F',38,204);20
21
22 create tabledepartment(23 dept_id int,24 dept_name varchar(100)25 );26
27 insert into department values
28 (200,'人事部'),29 (201,'技术部'),30 (202,'销售部'),31 (203,'财政部');32
33 mysql> select * fromemployee;34 +--------+----------+------+---------+
35 | emp_id | emp_name | age | dept_id |
36 +--------+----------+------+---------+
37 | 1 | A | 19 | 200 |
38 | 2 | B | 26 | 201 |
39 | 3 | C | 30 | 201 |
40 | 4 | D | 24 | 202 |
41 | 5 | E | 20 | 200 |
42 | 6 | F | 38 | 204 |
43 +--------+----------+------+---------+
44 6 rows in set (0.00sec)45
46 mysql> select * fromdepartment;47 +---------+-----------+
48 | dept_id | dept_name |
49 +---------+-----------+
50 | 200 | 人事部 |
51 | 201 | 技术部 |
52 | 202 | 销售部 |
53 | 203 | 财政部 |
54 +---------+-----------+
55 4 rows in set (0.01 sec)
1 内连接2 --查询两张表中都有的关联数据,相当于利用条件从笛卡尔积结果中筛选出了正确的结果。
3
4 select * from employee,department where employee.dept_id =department.dept_id;5 --select * from employee inner join department on employee.dept_id = department.dept_id;
6
7 +--------+----------+------+---------+---------+-----------+
8 | emp_id | emp_name | age | dept_id | dept_id | dept_name |
9 +--------+----------+------+---------+---------+-----------+
10 | 1 | A | 19 | 200 | 200 | 人事部 |
11 | 2 | B | 26 | 201 | 201 | 技术部 |
12 | 3 | C | 30 | 201 | 201 | 技术部 |
13 | 4 | D | 24 | 202 | 202 | 销售部 |
14 | 5 | E | 20 | 200 | 200 | 人事部 |
15 +--------+----------+------+---------+---------+-----------+
16
17 外连接18 --(1)左外连接:在内连接的基础上增加左边有右边没有的结果
19
20 select * from employee left join department on employee.dept_id =department.dept_id;21
22 +--------+----------+------+---------+---------+-----------+
23 | emp_id | emp_name | age | dept_id | dept_id | dept_name |
24 +--------+----------+------+---------+---------+-----------+
25 | 1 | A | 19 | 200 | 200 | 人事部 |
26 | 5 | E | 20 | 200 | 200 | 人事部 |
27 | 2 | B | 26 | 201 | 201 | 技术部 |
28 | 3 | C | 30 | 201 | 201 | 技术部 |
29 | 4 | D | 24 | 202 | 202 | 销售部 |
30 | 6 | F | 38 | 204 | NULL | NULL |
31 +--------+----------+------+---------+---------+-----------+
32
33 --(2)右外连接:在内连接的基础上增加右边有左边没有的结果
34
35 select * from employee RIGHT JOIN department on employee.dept_id =department.dept_id;36
37 +--------+----------+------+---------+---------+-----------+
38 | emp_id | emp_name | age | dept_id | dept_id | dept_name |
39 +--------+----------+------+---------+---------+-----------+
40 | 1 | A | 19 | 200 | 200 | 人事部 |
41 | 2 | B | 26 | 201 | 201 | 技术部 |
42 | 3 | C | 30 | 201 | 201 | 技术部 |
43 | 4 | D | 24 | 202 | 202 | 销售部 |
44 | 5 | E | 20 | 200 | 200 | 人事部 |
45 | NULL | NULL | NULL | NULL | 203 | 财政部 |
46 +--------+----------+------+---------+---------+-----------+
47
48 --(3)全外连接:在内连接的基础上增加左边有右边没有的和右边有左边没有的结果
49
50 --mysql不支持全外连接 full JOIN
51 --mysql可以使用此种方式间接实现全外连接
52
53 select * from employee RIGHT JOIN department on employee.dept_id =department.dept_id54 UNION
55 select * from employee LEFT JOIN department on employee.dept_id =department.dept_id;56
57
58
59 +--------+----------+------+---------+---------+-----------+
60 | emp_id | emp_name | age | dept_id | dept_id | dept_name |
61 +--------+----------+------+---------+---------+-----------+
62 | 1 | A | 19 | 200 | 200 | 人事部 |
63 | 2 | B | 26 | 201 | 201 | 技术部 |
64 | 3 | C | 30 | 201 | 201 | 技术部 |
65 | 4 | D | 24 | 202 | 202 | 销售部 |
66 | 5 | E | 20 | 200 | 200 | 人事部 |
67 | NULL | NULL | NULL | NULL | 203 | 财政部 |
68 | 6 | F | 38 | 204 | NULL | NULL |
69 +--------+----------+------+---------+---------+-----------+
70
71 --注意 union与union all的区别:union会去掉相同的纪录
72
73 --查询员工年龄大于等于25岁的部门
74
75 SELECT DISTINCTdepartment.dept_name76 FROMemployee,department77 WHERE employee.dept_id =department.dept_id78 AND age>25;79
80
81 --以内连接的方式查询employee和department表,并且以age字段的升序方式显示
82
83 selectemployee.emp_id,employee.emp_name,employee.age,department.dept_name84 fromemployee,department85 where employee.dept_id =department.dept_id86 order by age asc;87
88 --子查询是将一个查询语句嵌套在另一个查询语句中。
89 --内层查询语句的查询结果,可以为外层查询语句提供查询条件。
90 --子查询中可以包含:IN、NOT IN、ANY、ALL、EXISTS 和 NOT EXISTS等关键字
91 --还可以包含比较运算符:= 、 !=、> 、
1 --1. 带IN关键字的子查询
2
3 ---查询employee表,但dept_id必须在department表中出现过
4
5 select * fromemployee6 where dept_id IN
7 (select dept_id fromdepartment);8
9
10 +--------+----------+------+---------+
11 | emp_id | emp_name | age | dept_id |
12 +--------+----------+------+---------+
13 | 1 | A | 19 | 200 |
14 | 2 | B | 26 | 201 |
15 | 3 | C | 30 | 201 |
16 | 4 | D | 24 | 202 |
17 | 5 | E | 20 | 200 |
18 +--------+----------+------+---------+
19 rows in set (0.01sec)20
21
22
23 --2. 带比较运算符的子查询
24 --=、!=、>、>=、
25
26 --查询员工年龄大于等于25岁的部门
27 select dept_id,dept_name fromdepartment28 where dept_id IN
29 (select DISTINCT dept_id from employee where age>=25);30
31 --3. 带EXISTS关键字的子查询
32
33 --EXISTS关字键字表示存在。在使用EXISTS关键字时,内层查询语句不返回查询的记录。
34 --而是返回一个真假值。Ture或False
35 --当返回Ture时,外层查询语句将进行查询;当返回值为False时,外层查询语句不进行查询
36
37 select * fromemployee38 WHERE EXISTS
39 (SELECT dept_name from department where dept_id=203);40
41 --department表中存在dept_id=203,Ture
42
43
44 select * fromemployee45 WHERE EXISTS
46 (SELECT dept_name from department where dept_id=205);47
48 --Empty set (0.00 sec)
49
50
51 ps: create table t1(select * from t2);
1 表里只能有一个主键
2 每一张表不一定只有一个非空且唯一的字段
3 如果一张表里只有一个非空且唯一的,那他就是主键,如果有多个,那么第一个就是主键
搜索引擎
索引:
index key
算法:
1 hash
2 btree
python连接mysql
python3 pymysql
python2 mysqldb 名字不一样 注意