单表查询、多表查询、子查询

一、单表查询(*******)

1、完整语法(语法级别关键字的排列顺序如下)
select distinct 字段1,字段2,字段3,...from 库名.表名
where 约束条件
group by 分组依据
having 过滤条件
order by 排序字段
limit 限制显示的条数
;

必须要有的关键字如下:
select * from t1;

关键字执行的优先级:
from 找到表from
where 拿着where指定的约束条件,去文件/表中取出一条条几录
group by 将取出的一条条记录进行分组group by,如果没有group by则整体作为一组
having 将分组的结果进行having过滤
distinct 执行select 去重
order by 将结果按条件排序:order by
limit 限制结果的显示条数


def from():
pass

def where():
pass

def group():
pass

def having():
pass

def distinct():
pass

def order():
pass

def limit():
pass

def select():
f=from()
res1=where(f)
res2=group(res1)
res3=having(res2)
res4=distinct(res3)
res5=order(res4)
limit(res5)


#简单查询
select * from t1;
select id,name,sex from t1;

#避免重复DISTINCT
select distinct post from emp;

#通过四则运算查询
select name,salary*12 from emp;
select name,salary*12 as annual_salary from emp;

#定义显示格式
CONCAT() 函数用于连接字符串
select concat('名字',name) as new_name,concat('年龄',age) as new_age from emp;
select concat(name,':',age) from emp;

select concat(name,':',age,':',sex) from emp;
CONCAT_WS() 第一个参数为分隔符
select concat_ws(':',name,age,sex) as info from emp;



结合CASE语句:
SELECT
(
CASE
WHEN NAME = 'egon' THEN
NAME
WHEN NAME = 'alex' THEN
CONCAT(name,'_BIGSB')
ELSE
concat(NAME, 'SB')
END
) as new_name
FROM
emp;


2、 where

where字句中可以使用:

#1. 比较运算符:> < >= <= !=
#2. between 10 and 15值在10到15之间
#3. in(6,9,12) 值是6或9或12
#4. like 'egon%'
pattern可以是%或_,
%表示任意多字符
_表示一个字符
#5. 逻辑运算符:在多个条件直接可以使用逻辑运算符 and or not

select * from emp where id >=10 and id <=15; 等同于 select * from emp where id between 10 and 15;
select * from emp where id=6 or id=9 or id=12; 等同于
select * from emp where id in (6,9,12);

_代表任意单个字符
%代表任意无穷个字符
select * from emp where name like '__';
select * from emp where name like 'jin%';
select * from emp where id not in (6,9,12);
select * from emp where id not between 10 and 15;

关键字IS NULL(判断某个字段是否为NULL不能用等号,需要用IS)
select name,post_comment from employee where post_comment is null;

SELECT name,post_comment FROM employee
WHERE post_comment=''; 注意''是空字符串,不是null
ps:
执行
update employee set post_comment='' where id=2;
再用上条查看,就会有结果了


3、group by分组
什么分组:按照所有记录相同的部分进行归类,一定区分度低的字段
为何要分组:当我们要以组为单位进行统计时就必须分组,分组的目的是为了以组为单位进行统计的,
再去考虑单条记录毫无意义

# set global sql_mode="strict_trans_tables,only_full_group_by";
# 注意:分组之后,只能查到分组的字段以及组内多条记录聚合的成果
select * from emp group by post;

# 聚合函数
max
min
avg
sum
count

# 统计出每个部门年龄30以上的员工的平均薪资
select post,avg(salary) from emp where age >=30 group by post;

# 注意:分组是在where之后发生的
mysql> select * from emp where max(salary) > 3000;
ERROR 1111 (HY000): Invalid use of group function


单独使用GROUP BY关键字分组
SELECT post FROM employee GROUP BY post;
注意:我们按照post字段分组,那么select查询的字段只能是post,想要获取组内的其他相关信息,需要借助函数

GROUP BY关键字和GROUP_CONCAT()函数一起使用
SELECT post,GROUP_CONCAT(name) FROM employee GROUP BY post;#按照岗位分组,并查看组内成员名
SELECT post,GROUP_CONCAT(name) as emp_members FROM employee GROUP BY post;

GROUP BY与聚合函数一起使用
select post,count(id) as count from employee group by post;#按照岗位分组,并查看每个组有多少人




4、 having 过滤条件
# where是在分组之前的过滤,即在分组之前做了一次整体性的筛选
# having是在分组之后的过滤,即在分组之后专门针对聚合的结果进行进一步的筛选

select post,avg(salary) from emp group by post having avg(salary)>10000;
select post,avg(salary) from emp group by post;


5、order by 排序

select * from emp order by age asc; # 默认asc升序-》从小到大
select * from emp order by age desc;# desc降序-》从大到小

select * from emp order by age asc,salary desc; # 先按照age升序排列,如果age相同则按照salary降序排

select post,avg(salary) from emp group by post order by avg(salary);

6、limit 限制显示的条件

select * from emp limit 3;

#薪资最高那个人的详细信息
select * from emp order by salary desc limit 1;

# 分页显示
select * from emp limit 0,5; # 从0开始往后取5条
select * from emp limit 5,5; #从5开始往后取5条


#正则表达式
select * from emp where name regexp '^jin.*(g|n)$';




二、多表查询(*******)

外连接语法:
select 字段列表
from 表1 inner/left/right/ join 表2
on 表1.字段 = 表2.字段;

1、笛卡尔积
select * from emp,dep;

select * from emp,dep where emp.dep_id = dep.id;

select * from emp,dep where emp.dep_id = dep.id and dep.name = "技术";

2、内连接:只取两张表有对应关系的记录
select * from emp inner join dep on emp.dep_id = dep.id;
select * from emp inner join dep on emp.dep_id = dep.id
where dep.name = "技术";


3、左连接: 在内连接的基础上保留左表没有对应关系的记录
select * from emp left join dep on emp.dep_id = dep.id;

4、右连接: 在内连接的基础上保留右表没有对应关系的记录
select * from emp right join dep on emp.dep_id = dep.id;

5、全连接:在内连接的基础上保留左、右面表没有对应关系的的记录
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;



三、子查询

子查询:就是将一个查询语句的结果用括号括起来当作另外一个查询语句的条件去用


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


# 每个部门最新入职的员工
select t1.id,t1.name,t1.hire_date,t1.post,t2.* from emp as t1
inner join
(select post,max(hire_date) as max_date from emp group by post) as t2
on t1.post = t2.post
where t1.hire_date = t2.max_date
;



select * from emp inner join dep on emp.dep_id = dep.id;
posted @ 2018-08-11 16:16  Shinonon  阅读(335)  评论(0编辑  收藏  举报