1.内连接
/*
连接条件的分类:
1.自连接 vs 非自连接
2.等值连接 vs 非等值连接
3.内连接 vs 外连接
多表查询的语法:sql92语法与sql99语法(主要使用sql99)
*/
#查询员工姓名及部门名称
SELECT first_name, department_name
FROM employees,departments #sql92
WHERE employees.`department_id` = departments.`department_id`;
#查询员工的姓名,部门名称和部门id
SELECT first_name, department_name,employees.`department_id`
FROM employees,departments #sql92
WHERE employees.`department_id` = departments.`department_id`;
#注意:多表查询最好都在字段前面加表名,即提升效率,也减少错误
#多表查询时会在每张表都查询该字段,不加表名效率低下
#给表起别名,form先执行不是顺序执行
SELECT e.first_name, d.department_name,e.`department_id`
FROM employees e,departments d #sql92
WHERE e.`department_id` = d.`department_id`;
/*
select...
from 表名1 join 表名2
on 连接条件
join 表名3
on 连接条件
...
order by ...
*/
#查询员工姓名及部门名称(sql99语法)
SELECT e.`first_name`,d.`department_name`
FROM employees e JOIN departments d
ON e.`department_id`=d.`department_id`;
#连接条件:
#非自连接(两张不同的表)
#等值连接(连接条件符号为=)
#内连接(只查找两张表中的匹配内容)
JOIN ON
2.各种连接形式UNION
#自连接
#查询员工及员工管理者的姓名
SELECT e1.first_name 员工姓名, e2.`first_name` 管理者姓名
FROM employees e1 JOIN employees e2
ON e1.`manager_id` = e2.`employee_id`;
#非等值连接
#查询员工薪水的等级
SELECT e.`salary`,j.`GRADE`
FROM employees e JOIN job_grades j
ON e.`salary` BETWEEN j.`LOWEST_SAL` AND j.`HIGHEST_SAL`;
#左外连接
#查询所有的员工姓名及部门名称。
SELECT e.`first_name` ,d.`department_name`
FROM employees e LEFT JOIN departments d
ON e.`department_id` = d.`department_id`;
#右外连接
SELECT e.`first_name`,d.`department_name`
FROM employees e RIGHT JOIN departments d
ON e.`department_id` = d.`department_id`;
#满外连接 - full join(mySQL不支持)
#union:可以将两个查询结果合并在一起(去重后)
SELECT e.`first_name`,d.`department_name`
FROM employees e LEFT JOIN departments d
ON e.`department_id` = d.`department_id`;
UNION
SELECT e.`first_name`,d.`department_name`
FROM employees e RIGHT JOIN departments d
ON e.`department_id` = d.`department_id`;
#查询员工姓名,部门名称,城市名(三表连接)
SELECT
FROM employees e JOIN departments d
ON e.`department_id` = d.`department_id`
JOIN locations l
ON d.`location_id` = l.`location_id`;
LEFT JOIN
RIGHT JOIN
FULL JOIN(MYSQL支持)
UNION
UNION ALL(不去重)
3.去重与飘号
#去重:distinct
#查询有员工的部门号
SELECT DISTINCT department_id
FROM employees
WHERE department_id IS NOT NULL;
#``:如果字段名与关键字相同,那么字段名需要使用``括起来
SELECT `select`;
DISTINCT
4.单行函数
一出一
/*
LOWER('SQL Course'):将所有内容变成小写
UPPER('SQL Course'):将所有内容变成大写
*/
SELECT LOWER('aAbBcC');
SELECT UPPER('aAbBcC');
/*
CONCAT():字符串拼接
SUBSTR():截取子串。开始位置;长度 ,初始位置为1
LENGTH():字符串长度
INSTR('helloworld','w'):w首次出现的位置
LPAD(salary,10,'*'):向右对齐
10:长度不够10用*补齐
RPAD():向左补齐
TRIM(''FROM' aaaa aaaa '):去除两边指定的字符
REPLACE('aaaaa','a','A'):将字符串中指定字符进行替换
*/
SELECT CONCAT('hello','world');
SELECT CONCAT(first_name,last_name)
FROM employees;
SELECT SUBSTR('hellolong',1,3);
SELECT first_name, LENGTH(first_name)
FROM employees;
SELECT INSTR('abcdefg','c');
SELECT LPAD(salary,10,'*'),RPAD(salary,10,'*')
FROM employees;
SELECT TRIM(' ' FROM 'aa bb cc'); #aa bb cc
SELECT REPLACE ('abcabcaaa','a','A'); #AbcAbcAAA
/*
ROUND:四舍五入
ROUND(45.926,2) 45.93
TRUNCATE:截断
TRUNCATE(45.926) 45
MOD:求余
MOD(1600,300) 100
*/
SELECT ROUND(45.926,2),ROUND(45.926,1),
ROUND(45.926,0),ROUND(45.926,-1); #50
SELECT TRUNCATE(45.926,2),TRUNCATE(45.926,1),
TRUNCATE(45.926,0),TRUNCATE(45.926,-1) #40
#注意:结果的正负与第一个参数(被模数)的正负有关
SELECT MOD(4,3),MOD(-4,-3),MOD(-4,3),MOD(4,-3);
/*
函数NOW()
VERSION()
*/
SELECT NOW();
SELECT VERSION(); #显示当前版本
LOWER(‘SQL Course’) :将所有内容变成小写
UPPER(‘SQL Course’) :将所有内容变成大写
CONCAT(‘Hello’, ‘World’) : 字符串拼接
SUBSTR(‘HelloWorld’,1,5) : 截取子串。1指的是 索引位置(从1开始)。5指的是长度
LENGTH(‘HelloWorld’) :子符串长度
INSTR(‘HelloWorld’, ‘W’) :W首次出现的位置
LPAD(salary,10,’‘) : 向右对齐
如果长度不够10用补齐
RPAD(salary, 10, ‘‘) :向左对齐
如果长度不够10用补齐
TRIM(‘H’ FROM ‘HelloWorld’):去除指定的字符
REPLACE(‘abcd’,’b’,’m’) :将字符串中的指定的字符进行替换
ROUND: 四舍五入
ROUND(45.926, 2) 45.93
TRUNCATE: 截断
TRUNCATE(45.926) 45
MOD: 求余
MOD(1600, 300) 100
#注意:结果的正负和第一个参数的正负有关(被模数)
NOW()
VERSION()
5.通用函数
/*
ifnull(字段,默认值) :如果字段的内容为null那么就返回默认值
*/
SELECT IFNULL(1,10),IFNULL(NULL,10);
#案例:查询所有人的工资(salary+奖金)。
SELECT first_name,salary+salary*IFNULL(commission_pct,0) 工资
FROM employees;
/*
case-when-then-else-end
格式:
case 字段名
when 值1 then 返回值1
when 值2 then 返回值2
when 值3 then 返回值3
.......
else 返回值n
end
格式二
case
when 判断式1 then 返回值1
when 判断式2 then 返回值2
when 判断式3 then 返回值3
.......
else 返回值n
end
*/
#案例:查询部门号为 10, 20, 30 的员工信息, 若部门号为 10,
#则打印其工资的 1.1 倍, 20 号部门, 则打印其工资的 1.2 倍,
#30 号部门打印其工资的 1.3 倍数
SELECT first_name,salary,department_id,CASE department_id
WHEN 10 THEN salary*1.1
WHEN 20 THEN salary*1.2
WHEN 30 THEN salary*1.3
ELSE salary
END new_salary
FROM employees
WHERE department_id IN(10,20,30);
ifnull(字段,默认值) :如果字段的内容为null那么就返回默认值
case-when-then-else-end
格式:
case 字段名
when 值1 then 返回值1
when 值2 then 返回值2
when 值3 then 返回值3
…….
else 返回值n
end
格式二
case
when 判断式1 then 返回值1
when 判断式2 then 返回值2
when 判断式3 then 返回值3
…….
else 返回值n
end
6.组函数(多行函数)
多出一
/*
AVG() :平均值
SUM() :求和
注意:数据只能是数值类型
MAX() :最大值
MIN() : 最小值
*/
SELECT MAX(first_name)
FROM employees;
SELECT MAX(salary),MIN(salary),AVG(salary),SUM(salary)
FROM employees;
/*
COUNT() :求数量
count(字段名):该字段数据不为null的有多少条。
count(*):该表中的数据有多少条
count(数值):该表中的数据有多少条,count(数值)效率高于count(*)
*/
SELECT COUNT(commission_pct),COUNT(*),COUNT(1)
FROM employees;
SELECT commission_pct
FROM employees
WHERE commission_pct IS NOT NULL;
/*
注意1:
思考:求平均值(avg)是否包括null?不包括null
*/
SELECT AVG(commission_pct),SUM(commission_pct)/107,SUM(commission_pct)/35
FROM employees;
/*
注意2:一旦select后面出现组函数(聚合函数,多行函数)就不能再出现其它字段。
除非该字段也出现在group by的后面。
*/
SELECT first_name,AVG(salary)
FROM employees;
AVG() :平均值
SUM() :求和
注意:数据只能是数值类型
MAX() :最大值
MIN() : 最小值
COUNT() :求数量
count(字段名):该字段数据不为null的有多少条。
count():该表中的数据有多少条
count(数值):该表中的数据有多少条,count(数值)效率高于count()
注意1:
思考:求平均值(avg)是否包括null?不包括null
不包括
注意2:一旦select后面出现组函数(聚合函数,多行函数)就不能再出现其它字段。
除非该字段也出现在group by的后面。
注意3:注意2中如果group by后面跟的是主键或者不为空唯一索引时,可以在select后随意添加其他元素。
SELECT emp_no,salary,(
select COUNT(DISTINCT(s2.salary))
from salaries s2
where s2.salary >= s1.salary
) `t_rank`
from salaries s1
order by s1.salary DESC,s1.emp_no