python-10-mysql
sql语句
sql是Structured Query Language(结构化查询语言)的缩写。SQL是专为数据库而建立的操作命令集,是一种功能齐全的数据库语言。
在使用它时,只需要发出“做什么”的命令,“怎么做”是不用使用者考虑的。SQL功能强大、简单易学、使用方便,已经成为了数据库操作的基础,并且现在几乎所有的数据库均支持sql。
sql规范
<1> 在数据库系统中,SQL语句不区分大小写(建议用大写) 。但字符串常量区分大小写。建议命令大写,表名库名小写;
<2> SQL语句可单行或多行书写,以“;”结尾。关键词不能跨多行或简写。
<3> 用空格和缩进来提高语句的可读性。子句通常位于独立行,便于编辑,提高可读性。
1 2 | SELECT * FROM tb_table WHERE NAME = "YUAN" ; |
<4> 注释:单行注释:--
多行注释:/*......*/
<5>sql语句可以折行操作
<6> DDL,DML和DCL

-- --SQL中 DML、DDL、DCL区别 . -- -- DML(data manipulation language): -- 它们是SELECT、UPDATE、INSERT、DELETE,就象它的名字一样,这4条命令是用来对数据库里的 -- 数据进行操作的语言 -- -- -- DDL(data definition language): -- DDL比DML要多,主要的命令有CREATE、ALTER、DROP等,DDL主要是用在定义或改变表(TABLE) -- 的结构,数据类型,表之间的链接和约束等初始化工作上,他们大多在建立表时使用 -- -- -- DCL(Data Control Language): -- 是数据库控制功能。是用来设置或更改数据库用户或角色权限的语句,包括(grant,deny,revoke等) -- 语句。在默认状态下,只有sysadmin,dbcreator,db_owner或db_securityadmin等人员才有权 -- 力执行DCL
关于数据库操作的sql语句
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | - - 1. 创建数据库(在磁盘上创建一个对应的文件夹) create database [ if not exists] db_name [character set xxx] - - 2. 查看数据库 show databases;查看所有数据库 show create database db_name; 查看数据库的创建方式 - - 3. 修改数据库 alter database db_name [character set xxx] - - 4. 删除数据库 drop database [ if exists] db_name; - - 5. 使用数据库 切换数据库 use db_name; - - 注意:进入到某个数据库后没办法再退回之前状态,但可以通过use进行切换 查看当前使用的数据库 select database(); |
数据表的增删改查
创建一张表
1 2 3 4 5 6 7 | - - 语法 create table tab_name( field1 type [完整性约束条件], field2 type , ... fieldn type )[character set xxx]; |
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | - - 创建一个员工表employee create table employee( id int primary key auto_increment , name varchar( 20 ), gender bit default 1 , - - gender char( 1 ) default 1 - - - - - 或者 TINYINT( 1 ) birthday date, job varchar( 20 ), salary double( 4 , 2 ) unsigned, resume text - - 注意,这里作为最后一个字段不加逗号 ); / * 约束: primary key (非空且唯一) :能够唯一区分出当前记录的字段称为主键! unique not null auto_increment :用于主键字段,主键字段必须是数字类型 * / |
查看表信息
1 2 3 4 | desc tab_name 查看表结构 show columns from tab_name 查看表结构 show tables 查看当前数据库中的所有的表 show create table tab_name 查看当前数据库表建表语句 |
修改表结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | - - ( 1 )增加列(字段) alter table tab_name add [column] 列名 类型[完整性约束条件][first|after 字段名]; alter table user add addr varchar( 20 ) not null unique first / after username; #添加多个字段 alter table users2 add addr varchar( 20 ), add age int first, add birth varchar( 20 ) after name; - - ( 2 )修改一列类型 alter table tab_name modify 列名 类型 [完整性约束条件][first|after 字段名]; alter table users2 modify age tinyint default 20 ; alter table users2 modify age int after id ; - - ( 3 )修改列名 alter table tab_name change [column] 列名 新列名 类型 [完整性约束条件][first|after 字段名]; alter table users2 change age Age int default 28 first; - - ( 4 )删除一列 alter table tab_name drop [column] 列名; - - 思考:删除多列呢?删一个填一个呢? alter table users2 add salary float ( 6 , 2 ) unsigned not null after name, drop addr; - - ( 5 )修改表名 rename table 表名 to 新表名; - - ( 6 )修该表所用的字符集 alter table student character set utf8; |
删除表
1 | drop table tab_name; |
表记录的增删改查
增加表记录
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | / * < 1 >插入一条记录: insert [into] tab_name (field1,filed2,.......) values (value1,value2,.......); 示例: insert into employee_new ( id ,name,birthday,salary) values ( 1 , 'yuan' , '1990-09-09' , 9000 ); insert into employee_new values ( 2 , 'alex' , '1989-08-08' , 3000 ); insert into employee_new (name,salary) values ( 'xialv' , 1000 ); < 2 >插入多条记录: insert [into] tab_name (field1,filed2,.......) values (value1,value2,.......), (value1,value2,.......) ... ; 示例: insert into employee_new values ( 4 , 'alvin1' , '1993-04-20' , 3000 ), ( 5 , 'alvin2' , '1995-05-12' , 5000 ); < 3 > set 插入: insert [into] tab_name set 字段名 = 值 示例:insert into employee_new set id = 12 ,name = "alvin3" ; * / |
修改表记录
1 2 3 4 5 6 7 8 9 10 11 | update tab_name set field1 = value1,field2 = value2,......[where 语句] / * UPDATE语法可以用新值更新原有表行中的各列。 SET 子句指示要修改哪些列和要给予哪些值。 WHERE子句指定应更新哪些行。如没有WHERE子句,则更新所有的行。 * / update employee_new set birthday = "1989-10-24" WHERE id = 1 ; - - - 将yuan的薪水在原有基础上增加 1000 元。 update employee_new set salary = salary + 4000 where name = 'yuan' ; |
删除表记录
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | delete from tab_name [where ....] / * 如果不跟where语句则删除整张表中的数据 delete只能用来删除一行记录 delete语句只能删除表中的内容,不能删除表本身,想要删除表,用drop TRUNCATE TABLE也可以删除表中的所有数据,词语句首先摧毁表,再新建表。此种方式删除的数据不能在 事务中恢复。 * / - - 删除表中名称为’alex’的记录。 delete from employee_new where name = 'alex' ; - - 删除表中所有记录。 delete from employee_new; - - 注意auto_increment没有被重置:alter table employee auto_increment = 1 ; - - 使用truncate删除表中记录。 truncate table emp_new; |
思考: 表中数据三条,id分别为1,2,3,突然插入一个id=7,那么下次作为主键的字增长的id会从几开始增长呢?(从7开始)
查询表记录(******)
1 2 3 4 5 6 7 8 | - - 查询语法: SELECT * |field1,filed2 ... FROM tab_name WHERE 条件 GROUP BY field HAVING 筛选 ORDER BY field LIMIT 限制条数 |
准备表和记录:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | - - - 准备表 CREATE TABLE ExamResult( id INT PRIMARY KEY auto_increment, name VARCHAR ( 20 ), JS DOUBLE , Django DOUBLE , OpenStack DOUBLE ); - - - 插入数据 INSERT INTO ExamResult VALUES ( 1 , "yuan" , 98 , 98 , 98 ), ( 2 , "xialv" , 35 , 98 , 67 ), ( 3 , "alex" , 59 , 59 , 62 ), ( 4 , "wusir" , 88 , 89 , 82 ), ( 5 , "alvin" , 88 , 98 , 67 ), ( 6 , "yuan" , 86 , 100 , 55 ); |
简单查询
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | - - ( 1 )select [distinct] * |field1,field2,...... from tab_name - - 其中 from 指定从哪张表筛选, * 表示查找所有列,也可以指定一个列 - - 表明确指定要查找的列,distinct用来剔除重复行。 - - 查询表中所有学生的信息。 select * from ExamResult; - - 查询表中所有学生的姓名和对应的英语成绩。 select name,JS from ExamResult; - - 过滤表中重复数据。 select distinct JS ,name from ExamResult; - - ( 2 )select 也可以使用表达式,并且可以使用: 字段 as 别名或者:字段 别名 - - 在所有学生分数上加 10 分特长分显示。 select name,JS + 10 ,Django + 10 ,OpenStack + 10 from ExamResult; - - 统计每个学生的总分。 select name,JS + Django + OpenStack from ExamResult; - - 使用别名表示学生总分。 select name as 姓名,JS + Django + OpenStack as 总成绩 from ExamResult; select name,JS + Django + OpenStack 总成绩 from ExamResult; select name JS from ExamResult; - - what will happen? - - - - >记得加逗号 |
使用where子句,进行过滤查询
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | - - 查询姓名为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排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 指定排序的列,排序的列即可是表中的列名,也可以是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分组查询
准备表和记录

CREATE TABLE order_menu( id INT PRIMARY KEY auto_increment, product_name VARCHAR (20), price FLOAT(6,2), born_date DATE, class VARCHAR (20) ); INSERT INTO order_menu (product_name,price,born_date,class) VALUES ("苹果",20,20170612,"水果"), ("香蕉",80,20170602,"水果"), ("水壶",120,20170612,"电器"), ("被罩",70,20170612,"床上用品"), ("音响",420,20170612,"电器"), ("床单",55,20170612,"床上用品"), ("草莓",34,20170612,"水果");
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | - - 注意,按分组条件分组后每一组只会显示第一条记录 - - group by字句,其后可以接多个列名,也可以跟having子句,对group by 的结果进行筛选。 - - 按位置字段筛选 select * from order_menu group by 5 ; - - 练习:对购物表按类名分组后显示每一组商品的价格总和 select class , SUM (price) from order_menu group by class ; - - 练习:对购物表按类名分组后显示每一组商品价格总和超过 150 的商品 select class , SUM (price) from order_menu group by class HAVING SUM (price)> 150 ; / * having 和 where两者都可以对查询结果进行进一步的过滤,差别有: < 1 >where语句只能用在分组之前的筛选,having可以用在分组之后的筛选; < 2 >使用where语句的地方都可以用having进行替换 < 3 >having中可以用聚合函数,where中就不行。 * / - - GROUP_CONCAT() 函数 SELECT id ,GROUP_CONCAT(name),GROUP_CONCAT(JS) from ExamResult GROUP BY id ; |
聚合函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | - - < 1 > 统计表中所有记录 - - COUNT(列名):统计行的个数 - - 统计一个班级共有多少学生?先查出所有的学生,再用count包上 select count( * ) from ExamResult; - - 统计JS成绩大于 70 的学生有多少个? select count(JS) from ExamResult where JS> 70 ; - - 统计总分大于 280 的人数有多少? select count(name) from ExamResult where (ifnull(JS, 0 ) + ifnull(Django, 0 ) + ifnull(OpenStack, 0 ))> 280 ; - - 注意:count( * )统计所有行; count(字段)不统计null值. - - SUM (列名):统计满足条件的行的内容和 - - 统计一个班级JS总成绩?先查出所有的JS成绩,再用 sum 包上 select JS as JS总成绩 from ExamResult; select sum (JS) as JS总成绩 from ExamResult; - - 统计一个班级各科分别的总成绩 select sum (JS) as JS总成绩, sum (Django) as Django总成绩, sum (OpenStack) as OpenStack from ExamResult; - - 统计一个班级各科的成绩总和 select sum (ifnull(JS, 0 ) + ifnull(Django, 0 ) + ifnull(Database, 0 )) as 总成绩 from ExamResult; - - 统计一个班级JS成绩平均分 select sum (JS) / count( * ) from ExamResult ; - - 注意: sum 仅对数值起作用,否则会报错。 - - AVG(列名): - - 求一个班级JS平均分?先查出所有的JS分,然后用avg包上。 select avg(ifnull(JS, 0 )) from ExamResult; - - 求一个班级总分平均分 select avg((ifnull(JS, 0 ) + ifnull(Django, 0 ) + ifnull(Database, 0 ))) from ExamResult ; - - Max 、 Min - - 求班级最高分和最低分(数值范围在统计中特别有用) select Max ((ifnull(JS, 0 ) + ifnull(Django, 0 ) + ifnull(OpenStack, 0 ))) 最高分 from ExamResult; select Min ((ifnull(JS, 0 ) + ifnull(Django, 0 ) + ifnull(OpenStack, 0 ))) 最低分 from ExamResult; - - 求购物表中单价最高的商品名称及价格 - - - SELECT id , MAX (price) FROM order_menu; - - id 和最高价商品是一个商品吗? SELECT MAX (price) FROM order_menu; - - 注意:null 和所有的数计算都是null,所以需要用ifnull将null转换为 0 ! - - - - - - - ifnull(JS, 0 ) |
limit记录条数限制
1 2 3 | SELECT * from ExamResult limit 1 ; SELECT * from ExamResult limit 2 , 5 ; - - 跳过前两条显示接下来的五条纪录 SELECT * from ExamResult limit 2 , 2 ; |
正则表达式
1 2 3 4 5 | SELECT * FROM employee WHERE emp_name REGEXP '^yu' ; SELECT * FROM employee WHERE emp_name REGEXP 'yun$' ; SELECT * FROM employee WHERE emp_name REGEXP 'm{2}' ; |
外键约束
创建外键
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | - - - 每一个班主任会对应多个学生 , 而每个学生只能对应一个班主任 - - - - 主表 CREATE TABLE ClassCharger( id TINYINT PRIMARY KEY auto_increment, name VARCHAR ( 20 ), age INT , is_marriged boolean - - show create table ClassCharger: tinyint( 1 ) ); INSERT INTO ClassCharger (name,age,is_marriged) VALUES ( "冰冰" , 12 , 0 ), ( "丹丹" , 14 , 0 ), ( "歪歪" , 22 , 0 ), ( "姗姗" , 20 , 0 ), ( "小雨" , 21 , 0 ); - - - - 子表 CREATE TABLE Student( id INT PRIMARY KEY auto_increment, name VARCHAR ( 20 ), charger_id TINYINT, - - 切记:作为外键一定要和关联主键的数据类型保持一致 - - [ADD CONSTRAINT charger_fk_stu]FOREIGN KEY (charger_id) REFERENCES ClassCharger( id ) ) ENGINE = INNODB; INSERT INTO Student(name,charger_id) VALUES ( "alvin1" , 2 ), ( "alvin2" , 4 ), ( "alvin3" , 1 ), ( "alvin4" , 3 ), ( "alvin5" , 1 ), ( "alvin6" , 3 ), ( "alvin7" , 2 ); DELETE FROM ClassCharger WHERE name = "冰冰" ; INSERT student (name,charger_id) VALUES ( "yuan" , 1 ); - - 删除居然成功,可是 alvin3显示还是有班主任 id = 1 的冰冰的; - - - - - - - - - - - 增加外键和删除外键 - - - - - - - - - ALTER TABLE student ADD CONSTRAINT abc FOREIGN KEY(charger_id) REFERENCES classcharger( id ); ALTER TABLE student DROP FOREIGN KEY abc; |
INNODB支持的ON语句
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | - - 外键约束对子表的含义: 如果在父表中找不到候选键,则不允许在子表上进行insert / update - - 外键约束对父表的含义: 在父表上进行update / delete以更新或删除在子表中有一条或多条对 - - 应匹配行的候选键时,父表的行为取决于:在定义子表的外键时指定的 - - on update / on delete子句 - - - - - - - - - - - - - - - - - innodb支持的四种方式 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - cascade方式 在父表上update / delete记录时,同步update / delete掉子表的匹配记录 - - - - - 外键的级联删除:如果父表中的记录被删除,则子表中对应的记录自动被删除 - - - - - - - - FOREIGN KEY (charger_id) REFERENCES ClassCharger( id ) ON DELETE CASCADE - - - - - - set null方式 在父表上update / delete记录时,将子表上匹配记录的列设为null - - 要注意子表的外键列不能为 not null FOREIGN KEY (charger_id) REFERENCES ClassCharger( id ) ON DELETE SET NULL - - - - - - Restrict方式 :拒绝对父表进行删除更新操作(了解) - - - - - - No action方式 在mysql中同Restrict,如果子表中有匹配的记录,则不允许对父表对应候选键 - - 进行update / delete操作(了解) |
多表查询(*****)
准备表

-- 准备两张表 -- company.employee -- company.department create table employee( emp_id int auto_increment primary key not null, emp_name varchar(50), age int, dept_id int ); insert into employee(emp_name,age,dept_id) values ('A',19,200), ('B',26,201), ('C',30,201), ('D',24,202), ('E',20,200), ('F',38,204); create table department( dept_id int, dept_name varchar(100) ); insert into department values (200,'人事部'), (201,'技术部'), (202,'销售部'), (203,'财政部'); mysql> select * from employee; +--------+----------+------+---------+ | emp_id | emp_name | age | dept_id | +--------+----------+------+---------+ | 1 | A | 19 | 200 | | 2 | B | 26 | 201 | | 3 | C | 30 | 201 | | 4 | D | 24 | 202 | | 5 | E | 20 | 200 | | 6 | F | 38 | 204 | +--------+----------+------+---------+ rows in set (0.00 sec) mysql> select * from department; +---------+-----------+ | dept_id | dept_name | +---------+-----------+ | 200 | 人事部 | | 201 | 技术部 | | 202 | 销售部 | | 203 | 财政部 | +---------+-----------+ rows in set (0.01 sec)
多表查询之连接查询
1.笛卡尔积查询
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | mysql> SELECT * FROM employee,department; - - select employee.emp_id,employee.emp_name,employee.age, - - department.dept_name from employee,department; + - - - - - - - - + - - - - - - - - - - + - - - - - - + - - - - - - - - - + - - - - - - - - - + - - - - - - - - - - - + | emp_id | emp_name | age | dept_id | dept_id | dept_name | + - - - - - - - - + - - - - - - - - - - + - - - - - - + - - - - - - - - - + - - - - - - - - - + - - - - - - - - - - - + | 1 | A | 19 | 200 | 200 | 人事部 | | 1 | A | 19 | 200 | 201 | 技术部 | | 1 | A | 19 | 200 | 202 | 销售部 | | 1 | A | 19 | 200 | 203 | 财政部 | | 2 | B | 26 | 201 | 200 | 人事部 | | 2 | B | 26 | 201 | 201 | 技术部 | | 2 | B | 26 | 201 | 202 | 销售部 | | 2 | B | 26 | 201 | 203 | 财政部 | | 3 | C | 30 | 201 | 200 | 人事部 | | 3 | C | 30 | 201 | 201 | 技术部 | | 3 | C | 30 | 201 | 202 | 销售部 | | 3 | C | 30 | 201 | 203 | 财政部 | | 4 | D | 24 | 202 | 200 | 人事部 | | 4 | D | 24 | 202 | 201 | 技术部 | | 4 | D | 24 | 202 | 202 | 销售部 | | 4 | D | 24 | 202 | 203 | 财政部 | | 5 | E | 20 | 200 | 200 | 人事部 | | 5 | E | 20 | 200 | 201 | 技术部 | | 5 | E | 20 | 200 | 202 | 销售部 | | 5 | E | 20 | 200 | 203 | 财政部 | | 6 | F | 38 | 204 | 200 | 人事部 | | 6 | F | 38 | 204 | 201 | 技术部 | | 6 | F | 38 | 204 | 202 | 销售部 | | 6 | F | 38 | 204 | 203 | 财政部 | + - - - - - - - - + - - - - - - - - - - + - - - - - - + - - - - - - - - - + - - - - - - - - - + - - - - - - - - - - - + |
2.内连接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | - - 查询两张表中都有的关联数据,相当于利用条件从笛卡尔积结果中筛选出了正确的结果。 select * from employee,department where employee.dept_id = department.dept_id; - - select * from employee inner join department on employee.dept_id = department.dept_id; + - - - - - - - - + - - - - - - - - - - + - - - - - - + - - - - - - - - - + - - - - - - - - - + - - - - - - - - - - - + | emp_id | emp_name | age | dept_id | dept_id | dept_name | + - - - - - - - - + - - - - - - - - - - + - - - - - - + - - - - - - - - - + - - - - - - - - - + - - - - - - - - - - - + | 1 | A | 19 | 200 | 200 | 人事部 | | 2 | B | 26 | 201 | 201 | 技术部 | | 3 | C | 30 | 201 | 201 | 技术部 | | 4 | D | 24 | 202 | 202 | 销售部 | | 5 | E | 20 | 200 | 200 | 人事部 | + - - - - - - - - + - - - - - - - - - - + - - - - - - + - - - - - - - - - + - - - - - - - - - + - - - - - - - - - - - + |
3.外连接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | - - ( 1 )左外连接:在内连接的基础上增加左边有右边没有的结果 select * from employee left join department on employee.dept_id = department.dept_id; + - - - - - - - - + - - - - - - - - - - + - - - - - - + - - - - - - - - - + - - - - - - - - - + - - - - - - - - - - - + | emp_id | emp_name | age | dept_id | dept_id | dept_name | + - - - - - - - - + - - - - - - - - - - + - - - - - - + - - - - - - - - - + - - - - - - - - - + - - - - - - - - - - - + | 1 | A | 19 | 200 | 200 | 人事部 | | 5 | E | 20 | 200 | 200 | 人事部 | | 2 | B | 26 | 201 | 201 | 技术部 | | 3 | C | 30 | 201 | 201 | 技术部 | | 4 | D | 24 | 202 | 202 | 销售部 | | 6 | F | 38 | 204 | NULL | NULL | + - - - - - - - - + - - - - - - - - - - + - - - - - - + - - - - - - - - - + - - - - - - - - - + - - - - - - - - - - - + - - ( 2 )右外连接:在内连接的基础上增加右边有左边没有的结果 select * from employee RIGHT JOIN department on employee.dept_id = department.dept_id; + - - - - - - - - + - - - - - - - - - - + - - - - - - + - - - - - - - - - + - - - - - - - - - + - - - - - - - - - - - + | emp_id | emp_name | age | dept_id | dept_id | dept_name | + - - - - - - - - + - - - - - - - - - - + - - - - - - + - - - - - - - - - + - - - - - - - - - + - - - - - - - - - - - + | 1 | A | 19 | 200 | 200 | 人事部 | | 2 | B | 26 | 201 | 201 | 技术部 | | 3 | C | 30 | 201 | 201 | 技术部 | | 4 | D | 24 | 202 | 202 | 销售部 | | 5 | E | 20 | 200 | 200 | 人事部 | | NULL | NULL | NULL | NULL | 203 | 财政部 | + - - - - - - - - + - - - - - - - - - - + - - - - - - + - - - - - - - - - + - - - - - - - - - + - - - - - - - - - - - + - - ( 3 )全外连接:在内连接的基础上增加左边有右边没有的和右边有左边没有的结果 - - mysql不支持全外连接 full JOIN - - mysql可以使用此种方式间接实现全外连接 select * from employee RIGHT JOIN department on employee.dept_id = department.dept_id UNION select * from employee LEFT JOIN department on employee.dept_id = department.dept_id; + - - - - - - - - + - - - - - - - - - - + - - - - - - + - - - - - - - - - + - - - - - - - - - + - - - - - - - - - - - + | emp_id | emp_name | age | dept_id | dept_id | dept_name | + - - - - - - - - + - - - - - - - - - - + - - - - - - + - - - - - - - - - + - - - - - - - - - + - - - - - - - - - - - + | 1 | A | 19 | 200 | 200 | 人事部 | | 2 | B | 26 | 201 | 201 | 技术部 | | 3 | C | 30 | 201 | 201 | 技术部 | | 4 | D | 24 | 202 | 202 | 销售部 | | 5 | E | 20 | 200 | 200 | 人事部 | | NULL | NULL | NULL | NULL | 203 | 财政部 | | 6 | F | 38 | 204 | NULL | NULL | + - - - - - - - - + - - - - - - - - - - + - - - - - - + - - - - - - - - - + - - - - - - - - - + - - - - - - - - - - - + - - 注意 union与union all 的区别:union会去掉相同的纪录 |
多表查询之复合条件连接查询
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | - - 查询员工年龄大于等于 25 岁的部门 SELECT DISTINCT department.dept_name FROM employee,department WHERE employee.dept_id = department.dept_id AND age> 25 ; - - 以内连接的方式查询employee和department表,并且以age字段的升序方式显示 select employee.emp_id,employee.emp_name,employee.age,department.dept_name from employee,department where employee.dept_id = department.dept_id order by age asc; |
多表查询之子查询
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | - - 子查询是将一个查询语句嵌套在另一个查询语句中。 - - 内层查询语句的查询结果,可以为外层查询语句提供查询条件。 - - 子查询中可以包含:IN、NOT IN、 ANY 、 ALL 、EXISTS 和 NOT EXISTS等关键字 - - 还可以包含比较运算符: = 、 ! = 、> 、<等 - - 1. 带IN关键字的子查询 - - - 查询employee表,但dept_id必须在department表中出现过 select * from employee where dept_id IN (select dept_id from department); + - - - - - - - - + - - - - - - - - - - + - - - - - - + - - - - - - - - - + | emp_id | emp_name | age | dept_id | + - - - - - - - - + - - - - - - - - - - + - - - - - - + - - - - - - - - - + | 1 | A | 19 | 200 | | 2 | B | 26 | 201 | | 3 | C | 30 | 201 | | 4 | D | 24 | 202 | | 5 | E | 20 | 200 | + - - - - - - - - + - - - - - - - - - - + - - - - - - + - - - - - - - - - + rows in set ( 0.01 sec) - - 2. 带比较运算符的子查询 - - = 、! = 、>、> = 、<、< = 、<> - - 查询员工年龄大于等于 25 岁的部门 select dept_id,dept_name from department where dept_id IN (select DISTINCT dept_id from employee where age> = 25 ); - - 3. 带EXISTS关键字的子查询 - - EXISTS关字键字表示存在。在使用EXISTS关键字时,内层查询语句不返回查询的记录。 - - 而是返回一个真假值。Ture或 False - - 当返回Ture时,外层查询语句将进行查询;当返回值为 False 时,外层查询语句不进行查询 select * from employee WHERE EXISTS (SELECT dept_name from department where dept_id = 203 ); - - department表中存在dept_id = 203 ,Ture select * from employee WHERE EXISTS (SELECT dept_name from department where dept_id = 205 ); - - Empty set ( 0.00 sec) ps: create table t1(select * from t2); |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构