表相关操作

一、数据类型

整型

分类

"""
TINYINT   SAMLLINT   MEDUIMINT  INT   BIGINT
"""

作用

存储年龄、等级、id、号码等等
以TINYINT为例:
    是否有符号
        默认情况下是带符号的
    超出会如何
        超出限制只存最大可接收值
create table t9(id tinyint);
insert into t9 values(-129),(256);

# 约束条件之unsigend  无符号
create table t10(id tinyint unsigned);
以INT为例:  
    create table t11(id int);
# int默认也是带符号的
# 整型默认情况下都是带有符号的


# 针对整型 括号内的宽度到底是干啥的
create table t12(id int(8));
insert into t12 values(123456789);  # 123456789


# 特例:
  只有整型括号里面的数字不是表示限制位数
id int(8)  
  如果数字没有超出8位,那么默认用空格填充至8位
  如果数据超出了8位,那么有几位就存几位(但是还是要遵守最大范围)

# 用0填充至8位
create table t13(id int(8) unsigned zerofill);

总结: 针对整型字段,括号内无需指定宽度,因为它默认的宽度已经足够显示所有的数据了。

浮点型

分类

FLOAT   DOUBLE   DECIMAL

作用

身高、体重、薪资
# 存储限制
    float(255,30)   # 总共255位,小数部分占30位
    double(255,30)   # 总共255位,小数部分占30位
    decimal(65,30)     # 总共65位,小数部分占30位


# 精确度验证
    create table t15(id float(255,30));
    create table t16(id double(255,30));
    create table t17(id decimal(65,30));

insert into t15 values(1.11111111111111111111111111111111);
insert into t16 values(1.11111111111111111111111111111111);
insert into t17 values(1.11111111111111111111111111111111);

# 精确度对比:
     float < double < decimal
     要结合应用场景使用  三者都能使用

字符串类型

分类

char    定长  
    char(4)   数据超过4个直接报错,不够四个字符空格补全
varchar   变长
    varrchar(4)   数据超过4个直接报错,不够有几个存几个
create table t18(name char(4));
create table t19(name varchar(4));

insert into t18 values('a');
insert into t19 values('a');

# 介绍一个小方法  char_length  统计字段的长度
select char_length(name) from t18;
select char_length(name) from t19;

首先可以肯定的是char硬盘上存的绝对是真正的数据,带有空格的
但是在显示的时候MySQL会自动将多余的空格剔除

# 再次修改sql_mode  让MySQL不要做自动剔除操作
set global sql_mode = 'STRICT_TRANS_TABLES,PAD_CHAR_TO_FULL_LENGTH';

char与varchar对比

char:
    缺点:浪费空间
    优点:存取都很简单,直接按照固定的字符数据存取即可
            jason  egon alex   wusir  tank
            存按照五个字符,取也直接按照五个字符取

varchar:
    优点:节省空间
    缺点:存取较为麻烦    
              1bytes+jason  1bytes+egon  1bytes+alex   1bytes+wusir  
              存的时候需要制作报头
              取得时候也需要先读取报头,之后才能读取真实数据

以前基本上用的char,其实现在用varchar的也挺多

补充:
  进了公司之后,完全不需要考虑字段类型和字段名以及各种约束
  因为产品经理给你发的邮件上以及全部指明了。

日期类型

分类

data :年月日 2021-1-19
  datatime:年月日时分秒  2021-1-19 18:21:11
  time:时分秒 18:21:11
  Year:2021
create table student(
id int,
name varchar(16),
born_year year,
birth date,
study_time time,
reg_time datetime
);

insert into student values(1,'egon','2021','1880-11-11','11:11:11','2021-1-19 11:11:11');

枚举与集合类型

分类

"""
枚举(enum)  多选一
集合(set)   多选多
"""

具体使用

枚举
create table user(
id int,
name char(16),
gender enum('male','female','others')
);

insert into user values(1,'jason','male');  # 正常
insert into user value(2,'egon','xxx');  # 报错
# 枚举字段 后期在存数据的时候只能从枚举里面选择一个存储
集合
create table teacher(
id int,
name char(16),
gender enum('male','female','other'),
hobby set('read','DSB','hecha')
);


insert into teacher values(1,'jason','male','read');  # 正常
insert into teacher values(2,'egon','female','DSB,hecha');  # 正常
insert into teacher values(3,'tank','other','生蚝');  # 报错
# 集合可以只写一个,但是不能写没有列举的

总结

字段类型
严格模式

约束条件
    not null
    zerofill
    unsigned

二、约束条件

default默认值

# 补充知识点:插入数据的时候可以指定字段
create table t1(
id int,
name char(16)
);

insert into t1(name,id) values('jason',1);



create table t2(
id int,
name char(16) not null,
gender enum('male','female','others')default 'male'
);

insert into t2(id,name) values(1,'jason');
insert into t2 values(2,'egon','female');

unique唯一

# 单列唯一
create table t3(
id int unique,
name char(16)
);

insert into t3 value(1,'jason'),(1,'egon');
insert into t3 value(1,'jason'),(2,'egon');
  

# 联合唯一
'''
ip和port
单个都可以重复,但是加在一起必须是唯一的
'''
create table t4(
id int,
ip char(16),
port int,
unique(ip,port)
);

insert into t4 value(1,'127.0.0.1',8080);
insert into t4 value(2,'127.0.0.1',8081);
insert into t4 value(3,'127.0.0.2',8080);
insert into t4 value(4,'127.0.0.7',8080);
insert into t4 value(5,'127.0.0.1',8080);  # 报错

primary key主键

1、单单从约束效果上看primary key等价于not null + unique 
非空且唯一!!!

create table t5(id int primary key);

insert into t5 values(null);  # 报错
insert into t5 values(1),(1);  #  Duplicate entry '1' for key 'PRIMARY'
insert into t5 values(1),(2);  # 正常


2、它除了有约束效果之外,它还是Innodb存储引擎组织数据的依据
  Innodb存储引擎在创建表的时候必须要有primary key
  因为它类似于书的目录,能够帮助提示查询效率并且也是建表的依据
 1)一张表中有且只有一个主键,如果你没有设置主键,那么会从上往下搜索直到遇到一个非空且唯一的字段将它自动升级为主键

create table t6(
id int,
name char(16),
age int not null unique,
addr char(32) not null unique
);

 2)如果表中没有主键也没有其他如何非空且唯一字段,那么Innodb会采用自己内部提供的一个隐藏字段作为主键,隐藏意味着你无法使用到它
  就无法提示查询速度。



3、一张表中都通常都应该有一个主键字段,并且通常将id/uid/sid字段作为主键。
# 单个字段主键
create table t6(
id int primary key,
name char(16)
);

# 联合主键(多个字段联合起来作为表的主键,本质还是一个主键)
create table t7(
ip char(16),
port int,
primary key(ip,port)
);


也就意味着 以后我们在创建表的时候id字段一定要加primary key

auto_increment自增

当编号特别多的时候,人为的去维护太麻烦

create table t8(
id int primary key auto_increment,
name char(16)
);
insert into t8(name) value('jason'),('egon'),('tank');
# 注意 auto_increment 通常都是加在key键上 不能给普通字段加
create table t9(
id int primary key auto_increment,
name char(16),cid int auto_increment
);
# 报错:# ERROR 1075 (42000): Incorrect table definition; there can be only one auto column and it

结论

以后在创建表的 id(数据的唯一表示uid、sid、id) 字段的时候
id int primary key auto_increment

补充

delete from 在删除表中数据的时候,主键的自增不会停止

truncate t1 清空表数据并且重置主键

三、表与表之间建关系

定义一张员工表,表中有很多字段
id  name  gender  dep_name  dep_desc

1、该表的组织结构不是很清晰(可以忽视)
2、浪费硬盘空间(可忽视)
3、数据的扩展性极差(无法忽视)

# 如何优化?
'''
上述问题就类似于你将所有的代码都写在了一个py文件中
将员工表拆分成   员工表和部门表
'''

外键

"""
外键就是帮助我们建立表与表之间关系的
foregin key
"""

表关系

"""
表与表之间最多只有四种关系
    一对多关系
    在MySQL的关系中没有多对一一说
    一对多 多对一 都叫一对多!!!
    多对多关系
    一对一关系
    没有关系
"""

一对多关系

判断表与表关系的时候,前期不熟悉的情况下,一定要按照我给你的建议:
换位思考  分别站在两张表的角度考虑

员工表与部门表为例
    先站在员工表
        思考一个员工能否对应多个部门(一条员工数据能否对应多条部门数据)
        不能!!!
        (不能直接得出结论,一定要两张都考虑完全)
    再站在部门表
        思考一个部门能否对应多个员工(一个部门数据能否对应多员工数据)
        能!!!
    得出结论:
        员工表与部门表表示单向的一对多
        所以表关系就是一对多

SQL语句建立表关系

foreign key
    1、一对多表关系   外键字段建在多的一方
    2、在创建表的时候,一定要先建立被关联表
    3、在录入数据的时候,也必须先录入被关联表

create table dep(
id int primary key auto_increment,
dep_name char(16),
dep_dessc char(32)
);



create table emp(
id int primary key auto_increment,
name char(16),
gender enum('male','female','others') default 'male',
dep_id int,
foreign key(dep_id) references dep(id)
);


insert into dep(dep_name,dep_dessc) values('sb教学部','教书育人'),('外交部','多人外交'),('nb技术部','技术能力有限部门');
insert into emp(name,dep_id) values('jason',2),('egon',1),('tank',1),('keien',3);


# 修改dep表里面的ip字段
update dep set id=200 where id=2;   不行
# 删除dep表里面的数据   
delete from dep;   不行


如何做:
1、先删除教学部对应的员工数据  之后再删除部门
  操作太过繁琐
2、真正做到数据之间有关系 
  更新就同步更新
  删除就同步删除



******
级联更新
级联删除
******
create table dep(
id int primary key auto_increment,
dep_name char(16),
dep_dessc char(32)
);


create table emp(
id int primary key auto_increment,
name char(16),
gender enum('male','female','others') default 'male',
dep_id int,
foreign key(dep_id) references dep(id) 
on update cascade  # 同步更新
on delete cascade  # 同步删除
);

insert into dep(dep_name,dep_dessc) values('sb教学部','教书育人'),('外交部','多人外交'),('nb技术部','技术能力有限部门');
insert into emp(name,dep_id) values('jason',2),('egon',1),('tank',1),('keien',3);

多对多关系

图书表和作者表

create table book(
id int primary key auto_increment,
title varchar(32),
price int,
auth_id int,
foreign key(auth_id) references author(id)
on update cascade  # 同步更新
on delete cascade  # 同步删除
);


create table author(
id int primary key auto_increment,
name varchar(32),
age int,
book_id int,
foreign key(book_id) reference book(id)
on update cascade  # 同步更新
on delete cascade  # 同步删除
);

按照上述的方式创建一个都别想成功!!!
其实我们只是想记录书籍和作者的关系
针对多对多字段表关系,不能在两张原有的表中创建外键
需要你单独再开设一张  专门用来存储两张表数据之间的关系



create table book(
id int primary key auto_increment,
title varchar(32),
price int
);

create table author(
id int primary key auto_increment,
name varchar(32),
age int
);

create table book2author(
id int primary key auto_increment,
author_id int,
book_id int,
foreign key(author_id) references author(id)
on update cascade
on delete cascade,
foreign key(book_id) references book(id)
on update cascade
on delete cascade
);

一对多关系 

id name age addr phone hobby email...
如果一个表的字段特别多,每次查询又不是所有的字段都能用得到
将表一分为二
  用户表:
    用户表 id name age
    用户详情表  id addr phone hobbby email...

站在用户表:
  一个用户能否对应多个用户详情   不能!!!
站在详情表:
  一个详情能否属于多个用户   不能!!!
结论:单向的一对多都不成立,那么两者之间的表关系
     就是一对一
     或者没有关系(非常好判断)


客户表和学生表
  在你们报名之前你们是客户端
  报名之后是学生(期间有一些客户不会报名)


一对一 外键字段在任意一方都可以,但是推荐你建在查询频率比较高的表中
create table userdeatil(
id int primary key auto_increment,
phtone int,
addr varchar(64)
);

create table user(
id int primary key auto_increment,
name varchar(32),
age int,
userdeatil_id int unique,
foreign key(userdeatil_id) references userdeatil(id)
on update cascade
on delete cascade
);

总结

表关系的建立需要用到 foreign key
    一对多
        外键字段建在多的一方
    多对多
        自己开设第三张存储
    一对一
        建在任意一方都可以,但是推荐你建在查询频率较高的表中

判断表之间关系的方式
    换位思考!!!
        员工与部门

        图书与作者
    
        作者与作者详情

四、修改表的完整语法大全

"""
# MySQL对大小是不敏感的

1、修改表名
    alter table 表名 rename 新表名;


2、增加字段
    alter table 表名 add 字段名 字段类型(宽度) 约束条件;
    alter table 表名 add 字段名 字段类型(宽度) 约束条件 first;
    alter table 表名 add 字段名 字段类型(宽度) 约束条件 after 字段名;


3、删除字段
    alter table 表名 drop 字段名;


4、修改字典
    alter table 表名 modify 字段名 字段类型(宽度) 约束条件;
    alter table 表名 change 旧字段名 新字段名 字段类型(宽度) 约束条件;
"""

五、复制表

"""
我们sql语句查询的结果其实也是一张虚拟表

create table 新表名 select * from 旧表;   不能复制主键,外键...只能复制表结构和数据,假的还是假的

create table new_dep2 select * from dep where id>3;

"""

六、如何查询表

前期准备

create table emp(
id int not null unique auto_increment,
name varchar(20) not null,
sex enum('male','female') not null default 'male',
age int(3) unsigned not null default 28,
hire_data date not null,
post varchar(50),
post_comment varchar(100),
salary double(15,2),
office int, # 一个部门一个屋子
depart_id int
);

# 插入记录
# 三个部门:教学、销售、运营
insert into emp(name,sex,age,hire_data,post,salary,office,depart_id) values
('jason','male',18,'20170301','形象代言',17000.00,401,1),# 以下是教学部
('tom','male',18,'20170301','teacher',7300.33,401,1),
('kevin','male',35,'20120301','teacher',7300.33,401,1),
('tony','male',28,'20170301','teacher',7300.33,401,1),
('owen','male',18,'20170301','teacher',7300.00,401,1),
('jack','female',18,'20170301','teacher',9900.00,401,1),
('jenny','male',48,'19980301','teacher',7300.00,401,1),
('sank','male',18,'20170301','teacher',6300.00,401,1),# 以下是销售部门
('哈哈','male',18,'20170301','sale',6600.00,402,2),
('呵呵','male',18,'20170301','sale',6600.33,402,2),
('西西','male',18,'20170301','sale',6680.33,402,2),
('乐乐','male',18,'20170301','sale',6600.00,402,2),
('拉拉','male',18,'20160301','sale',95000.33,402,2),
('曾龙','male',18,'20190301','sale',6600.33,403,3),# 以下是运营部门
('程咬金','male',18,'20070301','operation',6600.33,403,3),
('程咬铁','female',18,'20070301','operation',6600.33,403,3),
('张铁蛋','male',18,'20170301','operation',700.33,403,3),
('王五','male',18,'19970301','operation',1700.33,403,3);


# 当表字段特别多,展示的时候错乱,可以使用G分行展示
select * from empG;

# 个别同学的电脑在插入中文的时候还是会出现乱码或者空白的现象
  你可以将字符编码统一设置成GBK

几个关键字的执行顺序

# 书写顺序
select id,name from emp where id > 3;
执行顺序:
  from 
  where
  select

'''
虽然执行顺序和书写顺序不一致,你在写sql语句的时候可能不知道怎么写
你就按照书写顺序的方式书写sql
  select * 先用*号占位
  之后去补全后面的sql语句
  最后将*号替换后面你想要的具体的的字段
'''

where约束条件

# 作用:是对整体数据的一个筛选操作
  
1、查询id大于等于3小于等于6的数据
select id,name,age from emp where id >=3 and id <= 6; 
select id,name,age from emp where id between 3 and 6;  # 两者等价

2、查询薪资是6600或者7300或者17000的数据
 select * from emp where salary=17000 or salary=7300 or salary=6600;
 select * from emp where salary in (6600,7300,17000);

3、查询员工姓名中包含字母o的员工的姓名和薪资
'''
模糊查询
  like
    % 匹配任意多个字符
    _ 匹配任意单个字符
'''
select name,salary from emp where name like '%o%';

4、查询员工姓名是由四个字符组成的 姓名和薪资  char_length()
select name,salary from emp where name like '____';
select name,salary from emp where char_length(name) = 4;

5、查询id小于3或者id大于6的数据
select * from emp where id not between 3 and 6;

6、查询薪资不在6600,7300,17000范围的数据
select * from emp where salary not in (6600,7300,17000);
 
7、查询岗位描述为空的员工姓名和岗位名  针对null不能用等号 用is
select name,post from emp where post_comment = NULL;  # Empty 
select name,post from emp where post_comment is NULL;
select name,port from emp where post_comment is not NULL;

group by分组

# 分组实际应用场景    分组应用场景非常的多
    男女比例
    部门平均薪资
    部门秃头率
    国家之间数据统计

1、按照部门分组
select * from emp group by post;
'''
分组之后,最小可操作单位应该是组,而不是组内的单个数据
     上述命令在你没有设置严格模式的时候是可以正常执行的, 返回的是分组之后,每个组的第一条数据,
     但是这不符合分组的规范,分组之后不应该考虑单个数据,而应该以组为操作单位(分组之后,每办法直接获取组内单个数据)

如果设置了严格模式,那么上述命令会直接报错

设置严格模式

"""
MySQL分组查询都有哪些特点
        分组之后默认只能获取到分组的依据 组内其他字段都无法直接获取了
            严格模式
                ONLY_FULL_GROUP_BY
"""
set global sql_mode='strict_trans_tables,only_full_group_by';
设置严格模式之后,分组 默认只能拿到分组的依据
select post from emp group by post;  
按照什么分组就只能拿到分组,其他字段不能直接获取,需要借助于一些方法


'''
什么时候需要分组???
  关键字  每个  平均  最高  最低
  集合函数
    max
    min
    sum
    count
    avg
'''
1、获取每个部门的最高薪资
  select post,max(salary) from emp group by post;
  select post as '部门',max(salary) as '最高薪资' from emp group by post;
  select post '部门',max(salary) '最高薪资' from emp group by post;
# as 可以给字段起别名,也可以直接省略不写,但是不推荐,因为省略的话语义不明确,容易错乱

2、获取每个部门的最低薪资  min
  select post,min(salary) from emp group by post;

3、获取每个部门的平均薪资  avg
  select post,avg(salary) from emp group by post;

4、获取每个部门的工资总和  sum
  select post,sum(salary) from emp group by post;

5、获取每个部门的人数  count
  select post,count(salary) from emp group by post; 
  select post,count(id) from emp group by post;  # 常用,符合逻辑
  select post,count(age) from emp group by post;
  select post,count(post_comment) from emo group by post;  # null不行

6、查询分组之后的部门名称和每个部门下所有的员工姓名  
    # group_concat 不单单可以支持你获取分组之后的其他字段值,还支持拼接操作
   select post,group_concat(name) from emp group by post;
  select post,group_concat(name,'_DSB') from emp group by post;
  select post,group_concat(name,':',salary) from emp group by post;
   # concat 不分组的时候用
  select concat('NAME:',name),concat('SAL:',salary) from emp;

# 补充 as语法不单单可以给字段起别名,还可以给表临时起别名
  select emp.name,emp.id from emp;
  select emp.name,emp.id from emp as t1;  # 报错
  select t1.name,t1.id from emp as t1;


# 查询每个人的年薪  12薪
  select name,salary*12 from emp;

分组注意事项

# 关键字 where 和 group by 同时出现的时候group by必须在where的后面
where先对整体数据进行过滤,之后再进行分组操作
where筛选条件不能使用聚合函数
select id,name,age from emp where max(salary) > 3000;  # 报错

select max(salary) from emp;  # 不分组,默认就是一组

# 统计各部门年龄在30岁以上的员工平均薪资
  1、先求所有年龄大于30岁的员工
    select * from emp where age>30;
  2、再对结果进行分组
     select * from emp where age>30 group by post;
    select post,avg(salary) from emp where age>30 group by post;

having分组之后的筛选条件

having的语法跟where是一致的
只不过having是在分组之后进行的过滤操作
即having是可以直接使用聚合函数的

# 统计各部门年龄在30岁以上的员工平均工资,并且保留平均薪资大于5000的部门
select post,avg(salary) from emp where age>30 group by post having avg(salary) > 5000;

distinct去重

'''
一定要注意,必须完全是一样的数据才可以去重!!!
一定不要将主键忽视了,有主键存在的情况下是不可能去重的
[{'id':1,'name':'jason'},{'id':2,'name':'egon'},{'id':3,'name':'jason'}] 

ORM 对象关系映射 让不懂SQL语句的人也能够非常牛逼的操作数据库
表              类
一条条的数据           对象
字段对应的值           对象的属性
你再写类 接意味着在创建表
用类生成对象 就意味者再创建数据
对象点属性 就是在获取数据字段对应的值

目的就是减轻python程序员的压力,只需要会python面向对象的知识点,就可以操作MySQL
'''
select distinct id,age from emp;  # 带有主键无法去重
select distinct age from emp;

order by排序

select * from emp order by salary;
select * from emp order by salary asc;  # 升序 从小到大
select * from emp order by salary desc;  # 降序  从大到小

order by 默认是升序 asc 该asc可以省略不写
也可以修改为降序    desc

select * from emp order by age desc,salary asc; # ...后面还可以再跟哦!
# 先按照age降序排,如果碰到age相同,则再按照salary升序排

统计各部门年龄在10岁以上的员工平均工资,并且保留平均薪资大于1000的部门,然后对平均工资降序
select post,avg(salary) from emp where age>10 group by post having avg(salary) > 1000 order by avg(salary) desc;

limit限制展示条数

select * from emp;

针对数据过多的情况,我们通常都是做分页处理
select * from emp limit 3;  # 只展示三条数据
select * from emp limit 0,5;  
select * from emp limit 5,5;  # 第六条开始往后面取五条
第一个参数是起始位置
第二个参数是展示条数

正则

select * from emp where name regexp '^j.*(n|y)$';

七、多表查询

准备表

建表
create table dep(
id int,
name varchar(16)
);

create table emp(
id int primary key auto_increment,
name varchar(16),
sex enum('male','female') not null default 'male',
age int,
dep_id int
);

# 插入数据
insert into dep values
(200,'技术'),
(201,'人力资源'),
(202,'销售'),
(203,'运营');

insert into emp(name,sex,age,dep_id) values
('jason','male',18,200),
('egon','female',48,201),
('kevin','male',18,201),
('nick','male',28,202),
('owen','male',18,203),
('jerry','female',18,204);

表查询

select * from dep,emp;  # 结果叫 笛卡尔积
'''
了解即可,不知道也没关系
'''


select * from emp,dep where emp.dep_id = dep.id;
'''
MySQL也知道 你在后面查询数据过程中 肯定也会经常用到拼表操作
所以特地给你开设了对应的方法
  inner join    内连接
  left join    左连接
  reight join    右连接
  union    全连接
'''

连表操作

inner join 内连接  只拼接两张表中共有的数据部分
select * from emp inner join dep on emp.dep_id = dep.id;

left join 左连接  左表所有的数据都展示出来,没有对应的项就用NULL
select * from emp left join dep on emp.dep_id = dep.id;

reight join 右连接   右表所有的数据都展示出来,没有对应的项就勇敢NULL
select * from emp right join dep on emp.dep_id = dep.id;

union 全连接   左右两表的数据都展示出来
select * from emp left join dep on emp.dep_id = dep.id
union
select * from emp right join dep on emp.dep_id = dep.id;

子查询

详情参见:https://www.cnblogs.com/linhaifeng/articles/7267596.html#_label4

子查询就是我们平时解决问题的思路
        分步骤解决问题
            第一步
            第二步
将一个查询语句的结果当做另外一个查询语句的条件去用


# 查询部门是技术或者人力资源的员工信息
  1、先获取部门的id号
  2、再去员工表里面筛选出对应的员工
  select id from dep where name='技术' or name='人力资源';
  select name from emp where dep_id in (200,201);

  select * from emp where dep_id in (select id from dep where name='技术' or name='人力资源');

1:子查询是将一个查询语句嵌套在另一个查询语句中。
2:内层查询语句的查询结果,可以为外层查询语句提供查询条件。
3:子查询中可以包含:IN、NOT IN、ANY、ALL、EXISTS 和 NOT EXISTS等关键字
4:还可以包含比较运算符:= 、 !=、> 、<等

总结

表的查询结果可以作为其他表的查询条件
也可以通过起别名的方式把它作为一张虚拟表与其他表进行关联

多表查询就两种方式
  先拼接表再查询
  子查询一步一步来



书写sql语句的时候select后面先用*占位,之后写完再改
书写较为复杂的sql语句的时候,不要想着一口气写完,写一点查一点看一点再写!!!
只要是设计数据查询相关的语法都不应该一次性写完,不太现实
在做多表查询的时候,联表操作和子查询可能会结合使用

补充知识点

查询平均年龄在25岁以上的部门
'''
只要是多表查询,就有两种思路
  联表  子查询
'''
# 联表操作
  1、先拿到部门和员工表 拼接之后的结果
  2、分析语义 得出需要进行分组
    select dep.name from emp inner join dep on emp.dep_id = dep.id group by dep.name having avg(age) >25;
   涉及到多表操作的时候一定要加上表的前缀

# 子查询操作
  select name from dep where id in(
select dep_id from emp group by dep_id having avg(age) > 25);


# 关键字exists(了解) 
  只返回布尔值 True False
  返回True的时候外层查询语句执行
  返回False的时候查询语句不再执行
    select * from emp where exists(select id from dep where id > 3);
   select * from emp where exists(select id from dep where id>300);

八、navicat可视化界面操作数据库

Navicat软件

"""
一开始学习python的时候,下载python解释器然后直接在终端书写
pycharm能够更加方便的帮助你书写pycharm代码
excel word pdf 

我们在终端操作MySQL,也没有自动提示也无法保存等等,不方便开发
Navicat内部封装了所有的操作数据库的命令
用户在使用它的时候只需要鼠标点点即可完成操作,无需书写sql语句
"""

安装

"""
直接百度搜索,有破解版的也有非破解版的
非破解的有试用期,如果不嫌麻烦 就直接使用
到期之后再重新装再使用,或者破解一下也很简单

https://www.cnblogs.com/poloyy/p/12231357.html

下载完成之后是一个压缩包,直接解压,然后点击安装,有提醒直接点击next即可

  navicat能够充当多个数据库的客户端

 

nacicat图形化界面有时候反应速度较慢,你可以选择刷新或者关闭当前窗口再次打开即可。

当你有一些需求该软件无法满则的时候,你就自己动手写sql

 
"""

提示

1、MySQL是不区分大小写的
        验证码忽略大小写
            内部统一转大写或者小写比较即可
            upper  lower
2、MySQL建议所有的关键字写大写     

3、MySQL中的注释 有两种
  --
  #

4、在navicat中如何快速的注释和解注释
  ctrl + ?  加注释
  ctrl + ?  基于上述操作再来一次就是解开注释

九、数据库查询题目讲解(多表操作)

详情参见:https://www.cnblogs.com/ZhZhang12138/p/14305231.html#shujukuchaxuntimujiangjie

技巧

1 面对复杂的查询题目的时候 不要捉急sql语句不要想着一口气写完 分步书写
2 只要是涉及到多表查询的时候 肯定用到联表操作和子查询
    联表操作 你可以无限制的联N多张表
        将两张表的结果起别名 编程一张表
        之后再去另外一张表拼接再起别名
        再去拼接...
原文地址:https://www.cnblogs.com/ZhZhang12138/p/14871624.html