1.内连接
/*连接条件的分类:1.自连接 vs 非自连接2.等值连接 vs 非等值连接3.内连接 vs 外连接多表查询的语法:sql92语法与sql99语法(主要使用sql99)*/#查询员工姓名及部门名称SELECT first_name, department_nameFROM employees,departments #sql92WHERE employees.`department_id` = departments.`department_id`;#查询员工的姓名,部门名称和部门idSELECT first_name, department_name,employees.`department_id`FROM employees,departments #sql92WHERE employees.`department_id` = departments.`department_id`;#注意:多表查询最好都在字段前面加表名,即提升效率,也减少错误#多表查询时会在每张表都查询该字段,不加表名效率低下#给表起别名,form先执行不是顺序执行SELECT e.first_name, d.department_name,e.`department_id`FROM employees e,departments d #sql92WHERE e.`department_id` = d.`department_id`;/*select...from 表名1 join 表名2on 连接条件join 表名3on 连接条件...order by ...*/#查询员工姓名及部门名称(sql99语法)SELECT e.`first_name`,d.`department_name`FROM employees e JOIN departments dON e.`department_id`=d.`department_id`;#连接条件:#非自连接(两张不同的表)#等值连接(连接条件符号为=)#内连接(只查找两张表中的匹配内容)
JOIN ON
2.各种连接形式UNION
#自连接#查询员工及员工管理者的姓名SELECT e1.first_name 员工姓名, e2.`first_name` 管理者姓名FROM employees e1 JOIN employees e2ON e1.`manager_id` = e2.`employee_id`;#非等值连接#查询员工薪水的等级SELECT e.`salary`,j.`GRADE`FROM employees e JOIN job_grades jON e.`salary` BETWEEN j.`LOWEST_SAL` AND j.`HIGHEST_SAL`;#左外连接#查询所有的员工姓名及部门名称。SELECT e.`first_name` ,d.`department_name`FROM employees e LEFT JOIN departments dON e.`department_id` = d.`department_id`;#右外连接SELECT e.`first_name`,d.`department_name`FROM employees e RIGHT JOIN departments dON e.`department_id` = d.`department_id`;#满外连接 - full join(mySQL不支持)#union:可以将两个查询结果合并在一起(去重后)SELECT e.`first_name`,d.`department_name`FROM employees e LEFT JOIN departments dON e.`department_id` = d.`department_id`;UNIONSELECT e.`first_name`,d.`department_name`FROM employees e RIGHT JOIN departments dON e.`department_id` = d.`department_id`;#查询员工姓名,部门名称,城市名(三表连接)SELECTFROM employees e JOIN departments dON e.`department_id` = d.`department_id`JOIN locations lON d.`location_id` = l.`location_id`;
LEFT JOIN
RIGHT JOIN
FULL JOIN(MYSQL支持)
UNION
UNION ALL(不去重)
3.去重与飘号
#去重:distinct#查询有员工的部门号SELECT DISTINCT department_idFROM employeesWHERE department_id IS NOT NULL;#``:如果字段名与关键字相同,那么字段名需要使用``括起来SELECT `select`;
DISTINCT
4.单行函数
一出一
/*LOWER('SQL Course'):将所有内容变成小写UPPER('SQL Course'):将所有内容变成大写*/SELECT LOWER('aAbBcC');SELECT UPPER('aAbBcC');/*CONCAT():字符串拼接SUBSTR():截取子串。开始位置;长度 ,初始位置为1LENGTH():字符串长度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 ccSELECT REPLACE ('abcabcaaa','a','A'); #AbcAbcAAA/*ROUND:四舍五入ROUND(45.926,2) 45.93TRUNCATE:截断TRUNCATE(45.926) 45MOD:求余MOD(1600,300) 100*/SELECT ROUND(45.926,2),ROUND(45.926,1),ROUND(45.926,0),ROUND(45.926,-1); #50SELECT 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 返回值1when 值2 then 返回值2when 值3 then 返回值3.......else 返回值nend格式二casewhen 判断式1 then 返回值1when 判断式2 then 返回值2when 判断式3 then 返回值3.......else 返回值nend*/#案例:查询部门号为 10, 20, 30 的员工信息, 若部门号为 10,#则打印其工资的 1.1 倍, 20 号部门, 则打印其工资的 1.2 倍,#30 号部门打印其工资的 1.3 倍数SELECT first_name,salary,department_id,CASE department_idWHEN 10 THEN salary*1.1WHEN 20 THEN salary*1.2WHEN 30 THEN salary*1.3ELSE salaryEND new_salaryFROM employeesWHERE 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_pctFROM employeesWHERE commission_pct IS NOT NULL;/*注意1:思考:求平均值(avg)是否包括null?不包括null*/SELECT AVG(commission_pct),SUM(commission_pct)/107,SUM(commission_pct)/35FROM 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 s2where s2.salary >= s1.salary) `t_rank`from salaries s1order by s1.salary DESC,s1.emp_no
