MySQL学习(二)数据查询DQL语言

一、基础查询

select完整的语法:

select 查询列表				7
from 表						1
【join type】 join 表2		2
on 连接条件					3
where 筛选条件				4
group by 分组字段			5
having 分组后的筛选			6
order by 排序的字段			8
limit offset,size;-- 分页	9

offset:要显示条目的起始索引(从0开始)
size:要显示的条目个数
(编号为执行顺序)
  1. 查询常量值

    select 100;
    select ‘john’;
    
  2. 查询表达式

    select 100*98
  3. 查询函数

    select version();
    
  4. 查询表中所有字段

    SELECT 
    	`employee_id`,#着重号`用来区分是否是关键字或者字段
    	`first_name`,
    	`last_name`,
    	`phone_number`,
    	`last_name`,
    	`job_id`,
    	`phone_number`,
    	`job_id`,
    	`salary`,
    	`commission_pct`,
    	`manager_id`,
    	`department_id`,
    	`hiredate` 
    FROM
    	employees ;
    或者:
    SELECT * FROM employees;# *:相当于按照表中字段顺序罗列表中的所有字段
    
  5. 起别名
    select所选字段后面可以指定别名以使查出来的结果所显示的字段更好理解,字段名与别名之间使用空格或as关键字间隔;

    select age+1 stu_age from student;
    select age+1 stu_age from student;
    
  6. 去重
    distinct:去除相同的行(“相同的行”指不同行之间的相同列中的数值相同)

    select distinct age from student;
    select distinct age,name from student;
    

    注意:该关键字必须紧跟select关键字的后面,即如下写法是错误的:

    select age,distinct name from student
    
  7. +号的作用

    • 两个操作数为数值型,则做加法运算
    • 只要其中一方为字符型,试图将字符型数值转换成数值型,如果转换成功,则继续做加法运算;如果转换失败,则将字符型数值转换成0
    • 只要其中一方为null,则结果肯定为null
    select 100+90;# 190
    select '123'+90;# 213
    select 'john'+90;# 90	
    select null+10;# null
    
  8. 使用concat连接字符串
    查询员工的名和姓连接成一个字段,并显示为姓名

    select concat(last_name,first_name) as 姓名 from employees;
    
  9. null相关

    • ifnull函数检测是否为null,如果为null,则返回指定的值,否则返回原本的值
      select ifnull(commission_pct, 0) as 奖金率, commission_pct from employees;
      
    • is null 和 is not null,isnull函数判断某字段或表达式是否为null,如果是,则返回1,否则返回0
      select * from student where address is null;# 查询地址为空的学生信息
      
      注意:is null不能写成 = null,同样,is not null不能写成!=null
    • ifnull函数检测是否为null,如果为null,则返回指定的值,否则返回原本的值:
      select ifnull(commission_pct, 0) as 奖金率, commission_pct from employees;
      

二、条件查询

语法:

select  查询列表  from  表名  where  筛选条件;
  1. 按条件表达式筛选
    关系条件:=、!=(<>)、<、=<、>、>=等

    select * from student where age<28;# 查询年龄小于28岁的学生信息
    # 查询部门编号不等于90号的员工名和部门编号
    SELECT last_name, department_id FROM employees WHERE department_id<>90;
    
  2. 按逻辑表达式筛选
    主要作用:用于连接条件表达式
    逻辑运算符:&&, ||, !, and, or ,not

    # 查询张姓且地址中含有北京的学生信息
    select * from student where name like '张%' and address like '%北京%';
    # 查询张姓或地址中含有北京的学生信息
    select * from student where name like '张%' or address like '%北京%';
    # 查询部门编号不是在90到110之间,或者工资高于15000的员工信息:
    select * from employees where department_id < 90 or department_id > 110 or salary > 15000;
    
  3. 模糊查询
    like:进行数据模糊查询

    • %:匹配0次或多次

      select * from student where name like '%%;#查询姓名中含有“李”字的学生信息
      
    • _:只匹配1次

      select * from student where name like '张_’;#查询两个字的张姓学生信息
      
    • escape:取消%或_字符的通配符特性

    • \为转义符

      #查询姓名中含有%字符的学生信息
      select * from student where name like '%#%%' escape#’
      SELECT * FROM `employees` WHERE last_name LIKE '_\_%'; # 查询第二个字符为下划线。\为转义符
      
      注意:
         - escape后面单引号中只能是单个字符;
         - escape后面可以是字母、#、$、,、\等字符;
      
  4. 范围查询

    • in:判断某字段的值是否属于in列表中的某一项

      特点:
        	①使用in提高语句简洁度
        	②in列表的值类型必须一致或兼容
        	③in列表中不支持通配符
      
      select * from student where age in(10,17,24);
      #上面SQL语句等效于下面语句
      select * from student where age = 10 or age=17 or age = 24;
      
    • between 下限 and 上限

      特点
        	①包含临界值
        	②两个临界值不要调换顺序
      
      #查询年龄在10~28之间的学生信息
      select * from student where age between 10 and 28;
      #上面SQL语句等效于该SQL语句
      select * from student where age >= 10 and age<=28;
      

      注意:

      “between 下限 and 上限”一定是小值在前大值在后,否则查不出数据;
      “between 下限 and 上限”查询数据包括边界值;
      
    • 安全等于 <=>

      # 查询没有奖金的员工名和奖金率
      SELECT last_name, commission_pct FROM employees WHERE commission_pct <=>NULL;
      
      is null:仅仅可以判断null值,可读性较高
      <=>:既可以判断null值,又可以判断普通的数值,可读性较低
      

三、排序查询

  • order by:对查询结果进行排序,必须置于SQL语句的最后,

  • 语法:

    select 查询列表
    from 表
    【where 筛选条件】
    order by 排序列表 【asc|desc】
    
  • [asc|desc]:指定排列策略,asc以升序排列,desc以降序排列,默认以升序排列。

  • 不同数据类型,升序的含义如下:

      数字类型:小值在前面显示;
      日期类型:早的日期在前面显示;
      字符类型:依据字母顺序显示,a在前,z最后;
      空值:显示在最后;
    
    select * from student order by age;#按照age升序排列
    select * from student order by age asc;#按照age升序排列
    select * from student order by age desc;#按照age降序排列
    
  • 多重排序:也称多列排序,即先以一个字段对查询结果进行排序,然后在这个排序的基础上再对另一个字段进行排序,最终显示经多次排序后的查询结果;

    #先依据年龄降序排列,当年龄相同时再依据姓名升序排列
    select * from student order by age desc,name asc;
    

四、常见函数

(一)单行函数

单行函数仅对单条数据中的列进行操作并且返回一个结果;

1.字符串函数

  1. length(column_name|str):获取参数值的字节个数

    SELECT LENGTH("张三丰haha");#13
    
  2. char_length(column_name|str):返回字符串中字符个数

    select char_length(name) length from student
    
  3. concat:拼接字符串;

    # concat 将多个字符串首尾连接后返回
    select concat(id,',',name,',',age,',',mobile,',',address) from student;
    
  4. concat_ws(separator,column_name1|str1,column_name2|str2,…):将多个字符串按照执行separator进行首尾相连;

    # concat_ws 将多个字段以,分隔并返回
    select concat_ws(',',id,name,age,mobile,address) from student;
    
  5. trim([{both | leading | trailing} [remstr] from]str):返回去掉str源字符串两端、前缀或后缀字符串remstr;不指定both、leading、trailing ,则默认为both,此时不能使用from关键字;不指定remstr,则去掉str两端的空格;

    select trim('  Tom  ') from dual;# 去掉两端的空格
    select trim(both 'a' from 'aaaTomaaa'); # 去掉两端的字符a
    select trim(leading 'a' from 'aaaTom');	# 去掉前缀的字符a
    select trim(trailing 'abc' from 'Tomabc'); # 去掉后缀的abc
    
  6. substr(str,pos[,len]):从源字符串str中的指定位置pos开始取一个字串并返回;

    注意:
    	pos:从1开始;
    	len:指定子串的长度,如果省略则一直取到字符串的末尾;len为负值表示从源字符串的尾部开始取起。
    	函数substr()是函数substring()的同义词。
    

    例子:

    select substring('hello world',7);
    select substring('hello world',7,5);
    
  7. replace(str, from_str, to_str):将源字符串str中所有子串form_str(大小写敏感替代成字符串to_str并返回替换后的字符串;

     select replace('prefix.mysql.com','prefix','www');# www.mysql.com
    
  8. reverse(str):返回字符串str反转结果

    select reverse('abcdef');
    
  9. strcmp(expr1,expr2):两个字符串相同则返回0;第一个小于第二个返回-1,否则返回1;

    select strcmp('text','text'); # 0
    select strcmp('aba','abc'); #-1
    
  10. upper/lower:将字符串变成大写/小写

    # 将姓变成大写,名变成小写,然后拼接:
    SELECT 
      CONCAT(UPPER(last_name), LOWER(first_name)) AS 姓名 
    FROM
      employees ;
    
  11. instr:返回子串第一次出现的索引,如果找不到返回0

    SELECT INSTR('杨不悔爱上了殷六侠','殷六侠');# 7
    
  12. lpad:用指定的字符实现左填充指定长度

    SELECT LPAD('殷素素',8,'*') AS out_put;# *****殷素素
    SELECT LPAD('殷素素',2,'*') AS out_put;# 殷素
    
  13. rpad:用指定的字符实现右填充指定长度

    SELECT RPAD('殷素素',8,'ab') AS out_put;# 殷素素ababa
    

2.数值函数

  1. mod(x,y):取x与y的余数;

    select mod(1,3) from dual
    
  2. round(x[,y]):返回参数x的四舍五入值,该值有y位小数;不指定第二个参数,则默认为0;

    SELECT ROUND(1.65);# 2
    SELECT ROUND(-1.4);# -1
    #四舍五入并保留小数点后2位
    SELECT ROUND(1.567,2);#1.57
    
  3. ceil:向上取整,返回>=该参数的最小整数

    SELECT CEIL(1.22);# 2
    
  4. floor:向下取整,返回<=该参数的最大整数

    SELECT FLOOR(-9.99);# -10
    
  5. truncate(x,y):返回数字x截断后的结果,该值有y位小数;

    select truncate(1.58,0),truncate(1.298,1);# 1 1.2
    
  6. rand:获取随机数,返回0-1之间的小数

3.日期函数

  1. now():获得当前日期+时间

    SELECT NOW();# 2021-02-13 14:24:47
    
  2. curdate:返回当前系统日期,不包含时间

    SELECT CURDATE();# 2021-02-13
    
  3. curtime:返回当前时间,不包含日期

    SELECT CURTIME();# 14:25:07
    
  4. 获取指定的部分,年、月、日、小时、分钟、秒

    SELECT YEAR('1998-1-1');# 1998
    SELECT YEAR(NOW());# 2021
    SELECT MONTH(NOW());# 2
    SELECT MONTHNAME(NOW());# February,以英文形式返回月
    
  5. str_to_date:将字符通过指定的格式转换成日期
    在这里插入图片描述

    SELECT STR_TO_DATE('2021','%Y');
    SELECT STR_TO_DATE('1998-3-2','%Y-%m-%d') AS out_put;# 1998-03-02
    
  6. date_format(date,format):获取指定格式的日期

    SELECT DATE_FORMAT(NOW(),'%Y%m%d%H%i%s');# 20210214014142
    SELECT DATE_FORMAT(NOW(),'%Y年%m月%d日') AS out_put;# 2021年02月14日
    
  7. datediff:返回两个日期相差的天数

    select datediff(now(),'1998-07-28');# 8238
    

4.其他函数

SELECT VERSION():	当前数据库服务器的版本
SELECT DATABASE():	当前打开的数据库
SELECT USER():		当前用户
password('字符'):	返回该字符的密码形式
md5('字符'):		返回该字符的md5加密形式
  1. convert(value,type):将value转换为type类型,type可以是char(字符型)、date(日期型)、time(时间型)、datetime(日期时间型)、signed(整型) 和decimal(浮点型)类型中的一个;

    select convert(now(),char(10));#2020-07-20
    
    select convert(now(),date); #2020-07-20 
    
    select convert(now(),time);#20:01:31
    
    select convert(now(),datetime);#2020-07-20 20:01:42
    
    select convert('99',signed)+1;#100
    
    select convert('99.99',decimal(5,2))+0.01;#100.00
    
  2. if(expr1,expr2,expr3): expr1为TRUE,返回expr2,否则返回expr3

    select if(name is NULL,'未知',name) from student;
    SELECT IF(10>5,'大','小');# 大
    
  3. ifnull(expr1,expr2):expr1为NULL,返回expr2,否则返回expr1

    select ifnull(name,'未知') from student;
    
  4. case函数

    • 使用一:switch case的效果

      语法:
        	case 要判断的字段或表达式
        	when 常量1 then 要显示的值1或语句1;
        	when 常量2 then 要显示的值2或语句2;
        	...
        	else 要显示的值n或语句n;
        	end
      
      /*
      案例:查询员工的工资,要求
      部门号=30,显示的工资为1.1倍
      部门号=40,显示的工资为1.2倍
      部门号=50,显示的工资为1.3倍
      其他部门,显示的工资为原工资
      */
      SELECT 
      	last_name,salary,department_id,
      	CASE department_id
      		WHEN 30 
      		THEN salary*1.1
      		WHEN 40 
      		THEN salary*1.2
      		WHEN 50 
      		THEN salary*1.3
      		ELSE salary
      	END AS '新工资'
      FROM 
      	employees;
      
    1. 使用二:类似于多重if

      case
       	when 条件1 then 要显示的值1或语句1
       	when 条件2 then 要显示的值2或语句2
       	...
       	else 要显示的值n或语句n
       	end
      
      /*
      案例:查询员工的工资的情况
      如果工资>20000,显示A级别
      如果工资>15000,显示B级别
      如果工资>10000,显示C级别
      否则,显示D级别
      */
      SELECT 
        salary,
        CASE
          WHEN salary > 20000 
          THEN 'A' 
          WHEN salary > 15000 
          THEN 'B' 
          WHEN salary > 10000 
          THEN 'C' 
          ELSE 'D' 
        END AS 工资级别 
      FROM
        employees ;
      

(二)分组函数

功能:用作统计使用,又称为聚合函数或统计函数或组函数

select sex,count(id) from student group by sex ;#获取student表中男女人数
注意:
	1、sum、avg一般用于处理数值型数据
	2、max、min、count可以处理任何类型数据
	3、分组函数都忽略null值
  1. avg():求平均值

    select avg(age) from student;#计算学生平均年龄,包括重复的年龄
    
  2. max():求最大值

    select max(age) from student;#获取学生表中最大年龄
    
  3. min():求最小值

    select min(age) from student;#获取学生表中最小年龄
    
  4. sum():求和

    select sum(age) from student;#计算学生表中年龄之和
    #和distinct搭配
    SELECT SUM(DISTINCT salary) FROM employees;# 去重之后再求和
    
  5. count():求行数

    # 多行函数忽略null列
    select count(address) from student;#当address数据为null时,不计数
    
    # 使用count() 统计一共有多少行
    SELECT COUNT(*) FROM employees;
    SELECT COUNT(1) FROM employees;
    
    效率:
    	MYISAM存储引擎下,count(*)的效率高
    	INNODB存储引擎下,count(*)和count(1)效率差不多,比count(字段)要高一些
    

五、分组查询

语法:

select 分组函数,列(要求出现在group by的后面)
from 表
【where 筛选条件】
group by 分组的列表
【having 分组后的筛选】
【order by 子句】
  • group by:用于将表中数据划分为若干个组,group by后面用于指定分组的依据

    #将student表学生按照sex分组,然后统计每组中的人数
    select sex,count(id) from student group by sex; 
    
  • 分组前筛选

    #查询邮箱中包含a字符的 每个部门的平均工资
    SELECT AVG(salary),department_id FROM employees WHERE email LIKE '%a%' GROUP BY department_id;
    
  • having子句对分组结果进行约束(分组后筛选)
    添加分组后的筛选用having,分组前的用where

    # 查询哪个名字重名
    select name,count(id) from student group by name having count(id) > 1;
    
  • 按多个字段分组

    #案例:查询每个工种每个部门的平均工资
    SELECT AVG(salary),department_id,job_id FROM employees GROUP BY department_id,job_id;
    
  • 添加排序

    #案例:查询每个部门每个工种的员工的平均工资,并按平均工资的高低显示
    SELECT AVG(salary),department_id,job_id FROM employees GROUP BY department_id,job_id ORDER BY AVG(salary) DESC;
    

六、连接查询

连接查询又称多表查询,当查询的字段来自于多个表时,就会用到连接查询

连接查询的分类:

按年代分类

  • sql92标准:仅仅支持内连接
  • sql99标准【推荐】:支持内连接+外连接(左外和右外)+交叉连接

按功能分类

  • 内连接:(inner join)

    等值连接
    非等值连接
    自连接
    
  • 外连接:(outer join)

    左外连接
    右外连接
    全外连接(mysql不支持)
    
  • 交叉连接(cross join)

(一)sql92标准

  1. 等值连接:最大特点是,连接条件为等量关系。

    #案例1:查询女神名和对应的男神名
    select name,boyname from beauty,boys where boys.id = boyfriend_id;
    
    #案例:查询有奖金的员工名、部门名
    select first_name,department_name from employees e,departments d 
    where e.department_id = d.department_id and commission_pct is not null;
    
    #案例:查询员工名、部门名和所在的城市(三表连接)
    select last_name,department_name,city 
    from employees e,departments d,locations l 
    where e.department_id = d.department_id and d.location_id = l.location_id ;
    
  2. 非等值连接:最大特点是,连接条件为非等量关系。

    #案例:查询员工的工资和工资级别
    select first_name,salary ,grade_level from job_grades ,employees where salary >=lowest_sal and salary <= highest_sal;select first_name,salary ,grade_level from job_grades ,employees where salary between lowest_sal and highest_sal;
    
  3. 自连接:最大特点是,一张表看作两张表。

    #案例:查询 员工名和上级的名称
    select e1.last_name,e2.last_name from employees e1,employees e2 
    where e1.manager_id = e2.employee_id;
    

(二)sql99标准

语法:

select 查询列表
from 表1 别名 【连接类型】
join 表2 别名 
on 连接条件
【where 筛选条件】
【group by 分组】
【having 筛选条件】
【order by 排序列表】

分类:

内连接(★):inner
外连接
	左外(★):left 【outer】
	右外(★):right 【outer】
	全外:full【outer】
交叉连接:cross 
  1. 内连接(inner join)

    语法:

    select 查询列表
    from 表1 别名
    inner join 表2 别名
    on 连接条件
    

    注意:

    1.inner可以省略
    2.筛选条件放在where后面,连接条件放在on后面,提高分离性,便于阅读
    
    1. 等值连接
    #案例:查询名字中包含e的员工名和工种名(添加筛选)
    select last_name,job_title from employees e 
    inner join jobs j on j.job_id = e.job_id 
    where last_name like '%e%';
    
    #案例:查询部门个数>3的城市名和部门个数,并按个数降序(添加分组+筛选+排序)
    select city,count(*) from departments d 
    join locations l on d.location_id = l.location_id 
    GROUP BY city having count(*) > 0 order by count(*) desc;
    
    #案例:查询员工名、部门名、工种名,并按部门名降序(添加三表连接)
    select last_name,department_name,job_title from employees e 
    INNER JOIN departments d on e.department_id = d.department_id 
    INNER JOIN jobs j on j.job_id = e.job_id 
    order by department_name desc;
    
    1. 非等值连接
    #查询员工的工资级别
    select last_name,salary,grade_level from employees inner join job_grades on salary <= highest_sal and salary >= lowest_sal;
     
     
    #查询工资级别的个数>20的个数,并且按工资级别降序
    select grade_level,count(*) from employees inner join job_grades where salary between lowest_sal and highest_sal 
    GROUP BY grade_level having count(*) > 20 order by grade_level desc;
    
    1. 自连接
    #查询员工的名字、上级的名字
    select e1.last_name,e2.last_name from employees e1 inner join employees e2 on e1.manager_id = e2.employee_id;
    
    #查询姓名中包含字符k的员工的名字、上级的名字
    select e1.last_name,e2.last_name from employees e1 inner join employees e2 on e1.manager_id = e2.employee_id where e1.last_name like '%k%';
    
  2. 外连接(outer join)

    语法:

     select 查询列表
     from 表1 别名
     left|right|full【outer】 join 表2 别名 on 连接条件
     where 筛选条件
     group by 分组列表
     having 分组后的筛选
     order by 排序列表
     limit 子句;
    

    含义:

    • 假设A和B表进行连接,使用外连接的话,AB两张表中有一张表是主表,一张表是副表,主要查询主表中的数据,捎带着查询副表。当副表中的数据没有和主表中的数据匹配上,副表自动模拟出NULL与之匹配。

    特点:

    • 外连接的查询结果为主表中的所有记录,如果从表中有和它匹配的,则显示匹配的值,如果从表中没有和它匹配的,则显示null
    • 左外和右外交换两个表的顺序,可以实现同样的效果
    • 左外连接(left [outer] join):返回的结果集中不仅包含表之间满足on连接条件的全部数据行,还包含左表(“left[outer] join”关键字左边的表)不满足on连接条件的数据行;

      select ui.*,addr.* from user_info ui 
      left join address addr on ui.id = addr.user_id;
      

      在这里插入图片描述

    • 右外连接(right [outer] join):返回的结果集中不仅包含表之间满足on连接条件的全部数据行,还包含右表(即“right [outer] join”关键字右边的表)不满足on连接条件的数据行;

       select ui.*,addr.* from user_info ui 
       right join address addr on ui.id = addr.user_id;
      

      在这里插入图片描述

      #案例:查询哪个部门没有员工
      #左外连接
      use myemployees;
      select d.*,e.employee_id from departments d 
      left join employees e on d.department_id = e.department_id 
      where e.employee_id is null;#右外连接
      select d.*,e.employee_id from employees e 
      right join departments d on d.department_id = e.department_id 
      where e.employee_id is null;
      
    • 全外连接(full [outer] join):返回的结果集中不仅包含表之间满足on连接条件的全部数据行,还包含左表(“full [outer] join”关键字左边的表)和右表(“full [outer join”关键字右边的表)中不满足on连接条件的数据行;(Mysql不支持)。

      select ui.*,addr.* from user_info ui 
      full join address addr on ui.id = addr.user_id;
      

      在这里插入图片描述

  3. 交叉连接(cross join)(也就是笛卡尔乘积)
    语法:

    select 查询列表
    from 表1 别名
    cross join 表2 别名;
    
    select ui.*,addr.* from user_info ui cross join address addr;
    

    在这里插入图片描述

七、子查询

  • 含义:
    出现在其他语句中的select语句,称为子查询或内查询;外部的查询语句,称为主查询或外查询
  • 分类:
    • 按子查询出现的位置:

      select后面:仅仅支持标量子查询
      from后面:支持表子查询
      where或having后面:支持标量子查询,列子查询,行子查询
      exists后面(相关子查询):支持表子查询
      
    • 按功能、结果集的行列数不同:

      标量子查询(单行子查询):结果集只有一行一列
      列子查询(多行子查询):结果集只有一列多行
      行子查询:结果集有一行多列
      表子查询:结果集一般为多行多列
      
  1. where或having后面

    后面可跟:标量子查询(单行子查询)、列子查询(多行子查询)、行子查询(多列多行)

    • 标量子查询,一般搭配着单行操作符使用(> < >= <= = <>)
    • 列子查询,一般搭配着多行操作符使用(IN、ANY/SOME、ALL)
      在这里插入图片描述
    • 子查询的执行优选于主查询执行,主查询的条件用到了子查询的结果
    • 标量子查询(单行子查询)
      #案例3:返回公司工资最少的员工的last_name,job_id和salary
      select last_name,job_id,salary from employees 
      where salary = (select min(salary) from employees);
      
      #案例4:查询最低工资大于50号部门最低工资的部门id和其最低工资
      select department_id,min(salary) from employees  
      group by department_id 
      having min(salary) > (select min(salary) from employees group by department_id having department_id = 50)
      
    1. 列子查询(多行子查询)
      #案例1:返回location_id是1400或1700的部门中的所有员工姓名
      select last_name,department_id from employees 
      where department_id in(select department_id from departments where location_id in(1400,1700));select last_name,department_id from employees
       where department_id = any(select department_id from departments where location_id in(1400,1700));
      
      #案例2:返回其它工种中比job_id为‘IT_PROG’工种任一工资低的员工的员工号、姓名、job_id 以及salary
      select employee_id,last_name,job_id,salary from employees 
      where salary < any(select salary from employees where job_id = 'IT_PROG') and job_id != 'IT_PROG';select employee_id,last_name,job_id,salary from employees 
      where salary < (select max(salary) from employees where job_id = 'IT_PROG') and job_id != 'IT_PROG';
      
      #案例3:返回其它部门中比job_id为‘IT_PROG’部门所有工资都低的员工   的员工号、姓名、job_id 以及salary
      select employee_id,last_name,job_id,salary from employees 
      where salary < all(select salary from employees where job_id = 'IT_PROG') and job_id != 'IT_PROG';select employee_id,last_name,job_id,salary from employees 
      where salary < (select min(salary) from employees where job_id = 'IT_PROG') and job_id != 'IT_PROG';
      
    2. 行子查询(多列多行)
      #案例:查询员工编号最小并且工资最高的员工信息
      # 多个字段的判断条件必须相同
      select * from employees 
      where (employee_id,salary) = (select min(employee_id),max(salary) from employees);
      
  2. select后面
    仅仅支持标量子查询

    #案例:查询每个部门的员工个数
    select department_id,(select count(*) from employees 
    where employees.department_id = departments.department_id) from departments;
    
  3. from后面
    将子查询结果充当一张表,要求必须起别名

    #案例:查询每个部门的平均工资的工资等级
    select avgs,department_id,job_grades.grade_level 
    from (select avg(salary) avgs,department_id from employees GROUP BY department_id) ag ,job_grades 
    where avgs BETWEEN lowest_sal and highest_sal;
    
  4. exists后面

    语法:exists(完整的查询语句)
    结果:1或0(如果查询的结果集存在,则为true;否则为false)

    #案例1:查询有员工的部门名
    select department_name from departments 
    where exists(select last_name from employees where employees.department_id = departments.department_id)select department_name from departments 
    where department_id in(select DISTINCT department_id from employees);
     
     
    #案例2:查询没有女朋友的男神信息
    select boys.* from boys 
    where not exists(select id from beauty where beauty.boyfriend_id = boys.id);select boys.* from boys 
    where id not in (select boyfriend_id from beauty);
    

八、分页查询

语法:

	select 查询列表
	from 表
	【join type】 join 表2
	on 连接条件
	where 筛选条件
	group by 分组字段
	having 分组后的筛选
	order by 排序的字段
	limit offset,size;
	offset:要显示条目的起始索引(从0开始)
	size:要显示的条目个数

特点:

1.limit语句放在查询语句的最后
2.公式:
	要显示的页数 page,每页的条目数size
	select 查询列表
	from 表
	limit (page-1)*size,size;
#案例1:查询前五条员工信息
select * from employees limit 0,5;
select * from employees limit 5;

#案例2:查询第11条——第25条
select * from employees limit 10,15;

#案例3:有奖金的员工信息,并且工资较高的前10名显示出来
select * from employees where commission_pct is not null 
order by salary desc limit 10;

九、联合查询

  • 联合,合并,将多条查询语句的结果合并成一个结果

  • 使用场景:
    要查询的结果来自于多个表,且多个表没有直接的连接关系,但查询的信息一致

  • 特点:

1.要求多条查询语句的查询列数是一致的
2.要求多条查询语句的查询的每一列的类型和顺序最好是一致的
3.union关键字默认去重,如果使用union all可以包含重复项

#案例:查询部门编号>90或邮箱包含a的员工信息
SELECT * FROM employees WHERE email LIKE '%a%' OR department_id>90;;SELECT * FROM employees  WHERE email LIKE '%a%'
UNION
SELECT * FROM employees  WHERE department_id>90;

#案例:查询中国用户中男性的信息以及外国用户中年男性的用户信息
SELECT id,cname FROM t_ca WHERE csex='男'
UNION ALL(不去重)
SELECT t_id,tname FROM t_ua WHERE tGender='male';
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值