mysql之sql语句
SQL语句中的注释:
-- 单行注释
/* .... */ 多行注释
每个sql语句结束需要写;来结束
需要在某个库中添加表需要use这个库
SQL DML 和DDL
DML 数据操作语言
DDL 数据定义语言
DML : 对数据库表的操作
CREATE TABLE 创建新表
1 -- 创建一个员工表employee 2 3 create table employee( 4 id int primary key auto_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 unique 16 not null 17 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 table users2 6 add addr varchar(20), 7 add age int first, 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 int after id; 14 15 -- (3)修改列名 16 alter table tab_name change [column] 列名 新列名 类型 [完整性约束条件][first|after 字段名]; 17 alter table users2 change age Age int default 28 first; 18 19 -- (4)删除一列 20 alter table tab_name drop [column] 列名; 21 -- 思考:删除多列呢?删一个填一个呢? 22 alter table users2 23 add salary float(6,2) unsigned not null after name, 24 drop addr; 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 FROM employee_new; --删除表中所有的记录 TRUNCATE TABLE emp_new; --使用truncate删除表中记录
SELECT 查询数据库表数据
1 SELECT *|field1,filed2 ... FROM tab_name 2 WHERE 条件 3 GROUP BY field 组 4 HAVING 筛选 5 ORDER BY field 6 LIMIT 限制条数 7 -- (1)select [distinct] *|field1,field2,...... from tab_name 8 -- 其中from指定从哪张表筛选,*表示查找所有列,也可以指定一个列 9 -- 表明确指定要查找的列,distinct用来剔除重复行。 10 11 -- 查询表中所有学生的信息。 12 select * from ExamResult; 13 -- 查询表中所有学生的姓名和对应的英语成绩。 14 select name,JS from ExamResult; 15 -- 过滤表中重复数据。 16 select distinct JS ,name from ExamResult; 17 18 -- (2)select 也可以使用表达式,并且可以使用: 字段 as 别名或者:字段 别名 19 20 -- 在所有学生分数上加10分特长分显示。 21 22 select name,JS+10,Django+10,OpenStack+10 from ExamResult; 23 -- 统计每个学生的总分。 24 select name,JS+Django+OpenStack from ExamResult; 25 -- 使用别名表示学生总分。 26 select name as 姓名,JS+Django+OpenStack as 总成绩 from ExamResult; 27 select name,JS+Django+OpenStack 总成绩 from ExamResult; 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 总成绩 from ExamResult where JS+Django+OpenStack>200 ; -- where字句中可以使用: -- 比较运算符: > < >= <= <> != between 80 and 100 值在10到20之间 in(80,90,100) 值是10或20或30 like '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 by JS; -- 对总分排序按从高到低的顺序输出 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 TABLE order_menu( 2 id INT PRIMARY KEY auto_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 by class; 28 29 -- 练习:对购物表按类名分组后显示每一组商品价格总和超过150的商品 30 select class,SUM(price)from order_menu group by class 31 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(*) from ExamResult; 6 -- 统计JS成绩大于70的学生有多少个? 7 select count(JS) from ExamResult where JS>70; 8 -- 统计总分大于280的人数有多少? 9 select count(name) from ExamResult 10 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总成绩 from ExamResult; 16 select sum(JS) as JS总成绩 from ExamResult; 17 -- 统计一个班级各科分别的总成绩 18 select sum(JS) as JS总成绩, 19 sum(Django) as Django总成绩, 20 sum(OpenStack) as OpenStack from ExamResult; 21 22 -- 统计一个班级各科的成绩总和 23 select sum(ifnull(JS,0)+ifnull(Django,0)+ifnull(Database,0)) 24 as 总成绩 from ExamResult; 25 -- 统计一个班级JS成绩平均分 26 select sum(JS)/count(*) from ExamResult ; 27 -- 注意:sum仅对数值起作用,否则会报错。 28 29 -- AVG(列名): 30 -- 求一个班级JS平均分?先查出所有的JS分,然后用avg包上。 31 select avg(ifnull(JS,0)) from ExamResult; 32 -- 求一个班级总分平均分 33 select avg((ifnull(JS,0)+ifnull(Django,0)+ifnull(Database,0))) 34 from ExamResult ; 35 -- Max、Min 36 -- 求班级最高分和最低分(数值范围在统计中特别有用) 37 select Max((ifnull(JS,0)+ifnull(Django,0)+ifnull(OpenStack,0))) 38 最高分 from ExamResult; 39 select Min((ifnull(JS,0)+ifnull(Django,0)+ifnull(OpenStack,0))) 40 最低分 from ExamResult; 41 -- 求购物表中单价最高的商品名称及价格 42 ---SELECT id, MAX(price) FROM order_menu;--id和最高价商品是一个商品吗? 43 44 SELECT MAX(price) FROM order_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 TABLE ClassCharger( 7 8 id TINYINT PRIMARY KEY auto_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 TABLE Student( 25 26 id INT PRIMARY KEY auto_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 CONSTRAINT abc 49 FOREIGN KEY(charger_id) 50 REFERENCES classcharger(id); 51 52 53 ALTER TABLE student DROP FOREIGN KEY abc; 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) REFERENCES ClassCharger(id) 69 ON DELETE CASCADE 70 71 72 ------set null方式 在父表上update/delete记录时,将子表上匹配记录的列设为null 73 -- 要注意子表的外键列不能为not null 74 75 FOREIGN KEY (charger_id) REFERENCES ClassCharger(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 table employee( 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 table department( 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 * from employee; 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.00 sec) 45 46 mysql> select * from department; 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_id 54 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 DISTINCT department.dept_name 76 FROM employee,department 77 WHERE employee.dept_id = department.dept_id 78 AND age>25; 79 80 81 --以内连接的方式查询employee和department表,并且以age字段的升序方式显示 82 83 select employee.emp_id,employee.emp_name,employee.age,department.dept_name 84 from employee,department 85 where employee.dept_id = department.dept_id 86 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 * from employee 6 where dept_id IN 7 (select dept_id from department); 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.01 sec) 20 21 22 23 -- 2. 带比较运算符的子查询 24 -- =、!=、>、>=、<、<=、<> 25 26 -- 查询员工年龄大于等于25岁的部门 27 select dept_id,dept_name from department 28 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 * from employee 38 WHERE EXISTS 39 (SELECT dept_name from department where dept_id=203); 40 41 --department表中存在dept_id=203,Ture 42 43 44 select * from employee 45 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 名字不一样 注意