03—— DQL语言基础(01)

一、基础查询

  • 如果查询的列表与关键字重名,或包含特殊字符,需要用单引号或双引号将其括起来。MySQL推荐双引号
  • null 与任何字段拼接、运算的结果都是 null,如:1+null   的结果为null
/* 1、查询列表可以是:表中的字段、常量值、表达式、函数
   2、select 可以查询多个字段
   3、查询的结果是一个虚拟的表格
*/

# select后的查询内容为要显示的查询内容,表名为从哪张表中去查
select 查询内容 from 表名;

# 起别名,方法一:
SELECT 10+8 AS result;         # result的值为10+8
# num1为firsr_name,num2为last_name
SELECT first_name AS num1,last_name AS num2 FROM [表名]

# 方法二:省略as
SELECT first_name num1,last_name num2 FROM [表名]

# 去重,将查询结果中的重复部分的去掉,如去除id中的重复部分
SELECT DISTINCT id FROM newTable;

# 加号的作用,只是数值运算
SELECT 10+8;

# 将查询的多个结果拼接起来,使用 CONCAT 函数
SELECT CONCAT("first"," name") AS result;


/* 判断是否为空,num01是可能为空的字段;当num01为空时,num02为返回的值,可以自行设定,如设为0
表示当num01为空时,返回0   
*/
SELECT IFNULL(num01,num02);

二、条件查询

1、常用通配符:

  •   任意多个字符,包含0个
  •     任意单个字符

2、条件查询的常见用法:

【注】:where 一定放在 from 之后;多个条件限制时,条件间用 and 进行连接 。

# 当where后的条件成立,就显示出来。其执行顺序为:先查看表名,再看筛选条件,最后再查询列表
/*
基本语法:
       select  
                查询列表
        from
                表名
        where
                筛选条件;

筛选分类:
        条件运算符(=、>、<、<=、>=、<>、!=)
        逻辑表达式(and or not && || !)
        模糊查询(like 、between and、in、is null、is not null)
*/
*******************************************************************

# 1、按条件表达式筛选出表id中所有num大于88的
SELECT
	*
FROM
	id
WHERE
	num>88;

# 2、按逻辑表达式筛选出age在30到60之间的
SELECT
	first_name,
    age
FROM
	id
WHERE
	age>30 AND age<60;

*******************************************************************

# 3-1、模糊查询like(一般查看是否包含某字段),查询员工名中包含小写字母a的所有员工,百分号表示通配符
SELECT
	*
FROM
	employees
WHERE
	theName LIKE '%a%';

# 3-2、模糊查询like,查询员工名中第4个字符为a的。a前有三个下划线
SELECT
	theName
FROM
	employees
WHERE
	theName LIKE '___a%';


# 3-3、自定义转义字符。查询员工名第二个字符为下划线。如下定义$ 为转义字符,也可以直接用斜线
SELECT
	theName
FROM
	employees
WHERE
	theName LIKE '_$_a%' ESCAPE '$' ;

# 4-1、模糊查询between and,员工编号在10到100之间的,包含临界值。
SELECT
	theNum
FROM
	employees
WHERE
	theNum BETWEEN 10 AND 100;
    # theNum NOT BETWEEN 10 AND 100;   不在10到100之间的



# 5-1、模糊查询in,查询员工工种编号是A、B、C其中之一的。
SELECT
	last_name,
	job_id
FROM
	employees
WHERE
	job_id IN('A','B','C');
# 等价于: job_id='A' or job_id='B' or job_id='C';

# 6-1、模糊查询is null 或is not null,判断员工中奖金为NULL的
SELECT
	last_name,
	bonus
FROM
	employees
WHERE
	bonus IS NULL;

# 6-2、安全等于 <=> ,可以判断一般的值,也可以判读null 值,但是可读性差。如下所示
SELECT
	last_name,
	bonus
FROM
	employees
WHERE
	bonus <=> NULL;

3、查询员工号为176的员工的姓名和部门号和年薪

【注】:因为奖金bonus可能为null,所以要加上ifnull 来进行判断,当bonus为空时,让其为0

SELECT
	last_name,
	department_id,
	salary*12*(1+IFNULL(bonus,0)) AS 年薪
FROM
	employees
WHERE
	number_id=176;

4、注意事项

  • MySQL中判断不等于可以使用 != ,但一般建议使用 <> 来进行判断
  • =<> 不能用于判断 null 值,常使用 is null 或 is not null 来进行判断

三、排序查询

1、语法

select 查询的内容
from 表名
[where  筛选条件]                      # 该项可有可无
order by 待排序的内容  [asc|desc]       # 将待排序的项目升序或降序排列

# asc 为升序,desc 将降序。省略时按默认的升序排序

2、应用

# 1、按工资由高到低的顺序,来显示员工下姓名、工种、薪资
SELECT first_name,job_id,salary 
FROM employees 
ORDER BY salary DESC;

# 2、查询部门编号>=90 的员工信息,按入职时间的先后顺序
SELECT *
FROM employees
WHERE department_id>=90
ORDER BY hiredate ASC;

# 3、按年薪的高低显示员工的信息和年薪
SELECT *, salary*12*(1+IFNULL(commission_pct,0)) 年薪
FROM employees
ORDER BY 年薪 ASC;

# 4、多个字段排序:如先按工资排序,若工资相同,再按员工编号排序。先排序的在前,后排序在后
SELECT *
FROM employees
ORDER BY salary ASC,employee_id DESC;

3、示例

# 查询员工姓名、部门、薪资。并按薪资降序、姓名升序来进行排列
SELECT last_name 姓名,department_id 部门,salary 薪资
FROM employees
ORDER BY salary DESC,last_name ASC;

      


四、常见函数

1、调用语法

# []中的内容可有可无,具体根据需要来定
select 函数名(实参列表) [from  表名]

2、函数分类:单行函数、分组函数

(1)、单行函数:

一、字符函数

# length 函数获取参数的字节数。在字符集为utf8下,英文占一个字节,中文占3个字节
SELECT LENGTH('hello');

# concat 函数,拼接字符
SELECT CONCAT('a','+','b');

# upper、lower,将字符大写或小写
SELECT UPPER('time');
SELECT LOWER('TiMe');

# substr、substring, 截取字符。MySQL中索引从1开始
SELECT SUBSTR('this is just a test',6) output;  #获取第六个字符之后的所有字符,包含第6个
SELECT SUBSTR('this is just a test',1,4) output; # 1为第一个字符,4为字符长度

# instr,返回字串第一次出现的索引。如:返回one在someone中第一次出现的位置
SELECT INSTR('someone','one');

# trim,返回字符串前后的空格,还可以去除字符串前后指定的字符
SELECT TRIM('a' FROM 'aaaaathis is justaaaaa');  #结果为:this is just

# lpad,用指定的字符实现左填充至指定的长度
SELECT LPAD('tom',6,'$');  #输出为 $$$tom ,一共6个字节

# rpad,指定字符填充至指定长度的右填充
SELECT RPAD('tom',6,'$');  #输出为 tom$$$ ,凑足6个字符

# replace,替换。如下将字符串中的like 替换成了do
SELECT REPLACE('hello there is some one who like this','like','do');

********************************************************************
二、数学函数

# round,四舍五入。如下四舍五入并保留两位小数
SELECT ROUND(3.1415926,4);

# ceil,向上取整,返回大于等于该数的值

# floor,向下取整

# truncate,截断。如下保留4位小数,其余的舍弃
SELECT TRUNCATE(3.1415926,4);

# mod,取余数。如下取10的余数
SELECT MOD(10,3);  # 等效于 10%3

********************************************************************
三、日期函数

# now,返回当前系统的日期+时间
SELECT NOW();

# curdate,返回当前系统日期,不包含时间
SELECT CURDATE();

# curtime,返回时间,不含日期

# 可以获取指定的部分,如:年、月、日、时分秒等
SELECT YEAR(NOW());    # 只有年
SELECT MONTH(NOW());   # 只有月
SELECT DAY(NOW());     # 只有天

# str_to_date:将日期格式的字符转换成指定格式的日期
SELECT STR_TO_DATE('2019-9-30','%Y-%c-%d') AS 'date';

# date_format:将日期转换成字符
SELECT DATE_FORMAT(NOW(),'%Y年%c月%d日');

********************************************************************
四、其它函数

SELECT VERSION();  # 查看版本
SELECT DATABASE(); # 查看当前数据库
SELECT USER();     # 查看当前用户

********************************************************************
五、流程控制函数

# if 函数,相当于if else,如果expt为true,输出up,否则输出down
SELECT IF(expt,'up','down');

/* case,用法一:类似switch case
语法:(注意:then后面为值时不加分号,为语句时要加分号)
case  要判断的字段或表达式
when  常量1  then 要显示的值1或语句1;
when  常量2  then 要显示的值2或语句2; 
..........
else  要显示的值n或语句n;
end
*/
/*  case 应用一:
查询员工工资、部门、及新工资。新工资计算方式如下:
部门为30,则新工资乘1.1
部门为40,则新工资乘1.2
部门为50,则新工资乘1.3
其余的为原工资
*/
SELECT 
	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  newSalary
FROM 
	employees;


/* case 用法二:类似多重if
语法:
case
when  条件1  then 要显示的值1
when  条件2  then 要显示的值2
..........
else  要显示的值n或语句n;
end
*/
/* case 应用二:
查询员工工资情况:
如果工资大于20000,显示A级别
如果工资大于15000,显示B级别
如果工资大于10000,显示C级别
否则显示D级别
*/
SELECT  salary,
CASE
WHEN salary>20000 THEN 'A'
WHEN salary>15000 AND salary<20000 THEN 'B'
WHEN salary>10000 AND salary<15000 THEN 'C'
ELSE 'C'
END AS theSalary
FROM employees;

应用实例:

查询有奖金的员工姓名、入职日期、奖金,并按照奖金升序进行排序:

SELECT last_name 姓名,DATE_FORMAT(hiredate,'%Y年%c月%d日') 入职日期,commission_pct 奖金
FROM employees
WHERE commission_pct IS NOT NULL
ORDER BY commission_pct ASC;

   

(2)、分组函数

  • 分组函数主要用于统计使用,又称为统计函数、聚合函数、组函数。
  • 其作用是传进一组值,经过处理后,返回一个值
  • 都会忽略 NULL
  • 可以与 distinct 搭配使用,来去除重复
  • 和分组函数一同查询的字段有限制
# sum 求和
# avg 平均值
# max 最大值
# min 最小值
# count 计数,计算非空值的个数,推荐使用count(*)

/* 对工资进行处理 */
SELECT 
	SUM(salary),
	AVG(salary),
	MAX(salary),
	MIN(salary),
	COUNT(salary)
FROM employees;

运行结果如下

  

# count 函数的详细介绍

# employees 中所有非空的字段都会被统计,常用于统计行数
select count(*) from employees;

# 统计行数的另一种方式,在count中可以用任何常量,如下使用 1
SELECT COUNT(1) FROM employees

五、分组查询

1、group by 子句将表中的数据分成若干组,

  • 查询的列表必须特殊,要求是分组函数和group by 后出现的字段
  • 注意各个语句的位置
  • from 的条件为可以直接在原表中进行筛选的字段
  • having 的条件为根据分组后的结果,再来进行筛选

其语法为:

select  对分组数据的操作,列(要求出现在group by 后面)
from  表名
[where 筛选条件]
group by 分组的列表
[having 根据分组后进行筛选的条件]
[order by 子句]

2、应用 :分组前的筛选

(1)、查询每个工种的最高工资,job_id 为工种

SELECT MAX(salary),job_id
FROM employees
GROUP BY job_id;

   

(2)、查询每个位置上的部门个数

SELECT COUNT(*),location_id 
FROM departments
GROUP BY location_id;

  

(3)、查询邮箱中包含a字符的,每个部门的平均工资

SELECT AVG(salary),department_id
FROM employees
WHERE email LIKE '%a%'
GROUP BY department_id;

(4)、查询有奖金的每个领导手下员工的最高工资

SELECT MAX(salary),manager_id
FROM employees
WHERE commission_pct IS NOT NULL
GROUP BY manager_id;

3、应用:分组后筛选。根据分组后的结果来进行筛选,条件为语句为: having

(1)、查询哪个部门的员工数大于2

【分析】此时每个部门的员工数需要分组统计后才能知道,所以需要分组后,再根据结果进行筛选

SELECT COUNT(*),department_id
FROM employees
GROUP BY department_id
HAVING COUNT(*)>2;

(2)、查询每个工种有奖金的员工的最高工资大于12000的工种编号和最高工资

SELECT MAX(salary),job_id
FROM employees
WHERE commission_pct IS NOT NULL         # 查看是否有奖金
GROUP BY job_id                          # 根据工种来进行分组
HAVING MAX(salary)>12000;                # 筛选结果中,最高工资大于12000的

4、按表达式或函数分组

按员工姓名的长度分组,查询每一组员工个数,筛选员工个数大于5的有哪些

SELECT COUNT(*) num,LENGTH(last_name) len_name
FROM employees
GROUP BY len_name
HAVING num>5;

    

5、按多个字段分组

查询每个部门每个工种的员工的平均工资,并按升序进行排列

SELECT AVG(salary),department_id,job_id
FROM employees
GROUP BY department_id,job_id
ORDER BY AVG(salary) ASC;

    

【总结】分组查询中筛选条件分为两类:分组前筛选、分组后筛选

  • 分组前筛选,数据源:原始表、                位置:group by 子句前、关键字:where
  • 分组后筛选,数据源:分组后的结果中、位置:group by 子句后、关键字:having
  • 分组函数作为条件的肯定是分组后筛选
  • 能用分组前筛选的优先使用分组前筛选
  • group by 子句支持单个字段分组,多字段分组(逗号隔开,不分先后顺序)

六、连接查询

1、基本知识

  • 含义:连接查询又称多表查询,当要查询的字段来自于多个表时,使用连接查询
  • 查询的字段一般要加上表名来进行限制,除非该字段只出现在一张表中,不会引起歧义
  • 使用连接查询一般要为表起别名,因为不同表中可能会有同样的字段名,通过别名来添加限制可以让代码简洁
  • 当为表起别名后,查询的字段就只能使用别名来进行限定,不能再使用原来的表名

2、等值连接的应用

(1)、查询两个表中id相匹配的员工

SELECT NAME,boyName   # name属于一个表,boyName属于另一个表
FROM beauty,boys
WHERE beauty.boyfriend_id=boys.id;  # 判断条件

(2)、查询员工名和对应的部门名(员工名和部门名分别在两张表中)

SELECT last_name,department_name
FROM employees,departments
WHERE employees.department_id=departments.department_id;

     

(3)、查询员工名、工种号、工种名

# 在查询的字段前需添加表名来进行限制,因为不同表中可能有同名的字段
SELECT employees.last_name,employees.job_id,job_title
FROM employees,jobs
WHERE employees.job_id=jobs.job_id;

# 为表起别名可以让代码简洁
SELECT e.last_name,e.job_id,j.job_title
FROM employees e,jobs j
WHERE e.job_id=j.job_id;

    

(4)、查询有奖金的每个部门的部门名、部门领导编号和该部门的最低工资

SELECT d.department_name,d.manager_id,MIN(salary)
FROM departments d,employees e
WHERE e.`commission_pct` IS NOT NULL
AND d.`department_id`=e.`manager_id`
GROUP BY d.department_name;

  

(5)、三表连接:查询员工名、部门名和所在城市

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`;

   

3、自连接应用(SQL92的标准)

 查询的字段位于同一张表中,此时可以将其看成两张表

如:查询员工名和其上级的名称

/*
将 employees e 看成员工表;employees m 看作上级表
相当于拿员工表的主管id和主管表进行对比,从而查出员工的上级
注意限制的条件是员工的主管id和主管表的id进行对比
*/
SELECT e.last_name,e.employee_id,e.manager_id,m.last_name,m.employee_id,m.manager_id
FROM employees e,employees m
WHERE e.manager_id=m.employee_id;

      

*************************************************************************************************************************

格式符的含义:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值