sql教程-DQL

DQL

Data Query Language

基础查询

select 查询列表 from 表名
查询列表可以是表中字段,常量值,表达式,函数

USE myemployees;   #表示在指定库操作
#1.查询单个字段
SELECT last_name FROM employees;

#2.查询多个字段
SELECT 
		last_name,
		salary,
		email 
FROM 
		employees;

#3.查询所有字段
SELECT * FROM employees;


#4.查询常量值
SELECT 100;
SELECT 'john';
SELECT 100%98;
SELECT VERSION();    #得到返回值

#5.起别名--后续连接操作,如果查询的字段有重名的情况,使用别名可以区分开来
#方式一
SELECT 100%98 as 结果;
SELECT last_name as 姓,first_name as 名 FROM  employees;
#方式二
SELECT last_name 姓,first_name 名 FROM  employees;
#PS:若别名有空格等,加上""或''表示一个整体
SELECT last_name as “out put” FROM  employees;

#6.去重-DISTINCT(不能写多个字段)
SELECT DISTINCT employee_id FROM employees;

#7.+作用:不能作字符串拼接,只能当运算符。其中一方为字符型,试图将字符型数值转换成数值型
如果转换成功,则继续做加法运算。失败则当成0继续运算。如果一方为null。则运算结果为Null

SELECT '123'+60;

#null遇到任何都为null。可以利用IFNULL(字段,0);将指定列的Null改为0
 
 #8.拼接字段
 SELECT CONCAT(last_name,first_name) as 姓名 FROM employees;
 
#9.显示表中结构
DESC departments;

条件查询

	SELECT 查询列表 FROM 表名 where 筛选条件
	常见符号:> < = <>(!+=) >= <= like "between and" in "is null"
					$$ || ! and or not
	
	# 按条件表达式筛选
	SELECT * FROM employees WHERE salary>12000; 
	
	#按逻辑表达式筛选
	SELECT * FROM employees WHERE salary>12000 AND salary <20000;

	#模糊查询
	#like经常与通配符使用。%表示多个字符(包含0个),_表示单个字符。也可用于数值型
	SELECT * FROM employees WHERE last_name LIKE '%a%';       #名中包含a
	#转移用\或者指定转移符号
	SELECT * FROM employees WHERE last_name LIKE '_\_a';
	SELECT * FROM employees WHERE last_name LIKE '_\$_a' ESCAPE '$';
	
	#BETWEEN AND  包含临界值。
	SELECT * FROM employees WHERE salary BETWEEN 10000 AND 20000;
	不在:	SELECT * FROM employees WHERE salary NOT BETWEEN 10000 AND 20000;

	# in:不支持通配符
	SELECT last_name,job_id FROM employees WHERE job_id IN('AD_VP','IT_PROG');

	# is null:不能用=判断null值
	SELECT last_name,commission_pct FROM employees WHERE commission_pct IS NULL;
	SELECT last_name,commission_pct FROM employees WHERE commission_pct IS NOT NULL;
	
	#安全等于:<=>:可以判断null,也可以当普通等于使用
	SELECT last_name,commission_pct FROM employees WHERE commission_pct <=> NULL;

排序查询

SELECT 查询列表 FROM 表名 where 筛选条件 order by 排序列表 [asc|desc]
order by子句一般是放在查询语句最后,limit子句除外

# 按某列排序  asc升序,desc降序。不写默认升序
SELECT * FROM employees ORDER BY salary DESC;

#按计算结果排序
SELECT *,salary*12*(1+IFNULL(commission_pct,0)) as 年薪 
FROM employees ORDER BY salary*12*(1+IFNULL(commission_pct,0)) DESC;

#按别名排序
SELECT *,salary*12*(1+IFNULL(commission_pct,0)) as 年薪 
FROM employees ORDER BY 年薪 DESC;

#带有函数
SELECT last_name,salary FROM employees ORDER BY LENGTH(last_name);

# 多关键词排序
SELECT * FROM employees ORDER BY salary ASC,employee_id DESC;

常见函数

SELECT 函数名(实参列表) FROM 
分类:
	单行函数:concat,length等,给一个值返回一个值
	分组(统计)函数:给一组值,返回一个值,又称聚会函数

#1、字符函数
SELECT LENGTH(‘数据库yyds’);        #一个汉字占三个字符(utf-8),jdk占两个字节
SELECT concat(last_name,'_',first_name) 姓名 FROM employees;
SELECT UPPER('jdk');  SELECT LOWER('JDK');
SELECT SUBSTR(‘I LOVE YOU’,1,3);                  #截取字符串。注意数据库的索引是从1开始的
SELECT INSTR('I LOVE YOU','YOU') AS output  #寻找第一次出现的起始索引,找不着返回0
SELECT TRIM(‘       LO  VE      ’)  ;                     #去空格,中间的不去
SELECT TRIM('a' FROM ‘aaaLOVEaaa’)  ;                     #去指定字符
SELECT LPAD ('数据库' ,10,'*');                    #左填充指定字符。右填充一个道理
SELECT REPLACE('I LOVE YOU','YOU','HIM');  #改指定字符串

#2、数学函数
SELECT ROUND(1.678,位数);   #四舍五入指定位数,默认到整数
SELECT CEIL(1.8);                 #向上取整
SELECT FLOOR(1.8);            #向下取整
SELECT TRUNCATE(1.65,位数);  #截断到第几位
SELECT MOD(10,3);              #取模

#3、日期函数
SELECT NOW();        #返回当前日期和时间
SELECT CURDATE(); #返回日期,不包含时间
SELECT CURTIME();#返回时间,不包含日期
SELECT YEAR(NOW()); #返回指定日期的年
SELECT MONTH(NOW()); #返回指定日期的月
……
SELECT STR_TO_DATE('9-13-1999','%m-%d-%Y');#将日期格式字符转换成指定格式日期
SELECT DATE_FORMAT('2018/6/6','%Y年%m月%d日'); #将日期转化为字符串

在这里插入图片描述


#4、其他函数
SELECT VERSION();  #查看版本
SELECT DATABASE();  #查看当前数据库
SELECT USER();   #查看当前用户
SELECT PASSWORD(str); #给字符串加密形式

#5、流程控制函数
	if函数:SELECT IF(10>5,'大','小');  #三元运算
	case函数:
		使用1:swithc case效果:
		case 要判断的字段和表达式
		when 常量1 then 要显示的语句或值
		when……
		else  要显示语句和值
		end
		
		使用2:多重if
		case
		when 条件1 then 要显示的值或表达式
		when 条件2 then ……
		……
		else then 要显示的值或表达式
		end

在这里插入图片描述
在这里插入图片描述

分组函数:sum求和 avg平均值 max最大值 min最小值 count计算个数
SELECT sum(salary) FROM  employees;
SELECT avg(salary) FROM  employees;
SELECT max(salary) FROM  employees;
SELECT min(salary) FROM  employees;
SELECT count(salary) FROM  employees;         #非空的值有几个
SELECT count(*) FROM  employees;         #统计表中函数
也可这么些:SELECT count(1) FROM  employees;         

分组查询

SELECT 分组函数,列(要求出现在group by 后面) FROM 表名 where 筛选条件 group by 条件 order by 排序列表 [asc|desc]
#明确where一定要放在from后面

#分组前的筛选
SELECT MAX(salary),job_id FROM employees GROUP BY job_id;  #每个工种的最高工资

#分组后的筛选
SELECT COUNT(*),department_id FROM employees GROUP BY department_id HAVING COUNT(*)>2;

总结:分组前筛选是原始表,用where(GROUP BY子句前面);分组后筛选是分组后的结果集,需要用having(GROUP BY子句后面)

#按表达式或函数分组
SELECT COUNT(*),LENGTH(last_name) FROM employees GROUP BY LENGTH(last_name) HAVING COUNT(*)>5;

#按多个字段分组
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) ASC ;

连接查询(多表查询)

sql92

#笛卡尔乘积现象(没有有效连接条件,因此N=n*m)
SELECT `name`,boyName FROM beauty,boys;

#限定
SELECT `name`,boyName FROM beauty,boys WHERE beauty.boyfriend_id = boys.id;

#分类:
	内连接:等值连接,非等值连接,自连接
	外连接:左外连接,右外连接,全外连接
	交叉连接

#因为有多表,因此尽量为表取别名以示区分

sql92连接语法:用where连接筛选条件和连接条件(注意下面sql99实现分离)
#1、等值连接
SELECT `name`,boyName FROM beauty,boys WHERE beauty.boyfriend_id = boys.id;
#当表名很长时,可以为表起别名。但如果为表起了别名,则查询的字段就不能使用原来的表名去限定
SELECT `name`,boyName FROM beauty be,boys b WHERE be.boyfriend_id = b.id;
#加限定:
SELECT `name`,boyName FROM beauty be,boys b WHERE be.boyfriend_id = b.id AND b.boyName IS NOT NULL.;

#2、非等值连接--利用其他运算符求解
SELECT salary,grade_level
FROM employees e,job_grades g
WHERE salary BETWEEN g.lowest_sal AND g.highest_sal;

#3、自连接--相同的表进行连接
use myemployees;
SELECT e.employee_id,e.last_name,e.manager_id,m.last_name
FROM employees e,employees m
WHERE e.manager_id=m.employee_id;

sql99

#sql99连接语法
SELECT 查询列表
FROM 表1 别名 【连接条件】
join 表2 别名
on 连接条件
where 筛选条件
GROUP BY 分组
HAVING 筛选条件
ORDER BY 排序列表
内连接:inner
外连接:
		左外:left 【outer】
		右外:right 【outer】
		全外:full 【ouder】
交叉连接:cross

#1、内连接--等值,非等值,内连接。inner可以省略
SELECT 查询列表 FROM 表1 别名  INNER join 表2 别名 on 连接条件
#两表连接
SELECT last_name,department_name 
FROM employees e
INNER JOIN departments d
ON e.department_id = d.department_id;
#多表连接
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 e.job_id = j.job_id
ORDER BY department_name DESC;

#2、外连接:没有匹配用null替代
#左外
SELECT b.`name`,bo.*
FROM beauty b
LEFT JOIN boys bo
ON b.boyfriend_id = bo.id;
#全外
SELECT b.*,bo.*
FROM beauty b
FULL JOIN boys bo
ON b.boyfriend_id = bo.id;

PS:更老的版本中,外连接这么写的
Select Student.Sno, Sname, Cno, Grade                               
From Student, SC                                                                                
Where Student.Sno=SC.Sno(*)
这里表示左外连接,即student没有与之匹配的SC都要(设为null)

#3、交叉连接--本质上是笛卡尔乘积,sql92语法用的是','
SELECT b.*,bo.*
FROM beauty b
CROSS JOIN boys bo;

子查询

出现在其他语句中的SELECT语句,称为子查询或内查询。外部的查询语句称为主查询
分类:
按主查询出现顺序:
	SELECT后面:仅支持标量子查询
	FROM后面:支持表子查询
	WHERE或HAVING后面:标量子查询,列子查询,行子查询(重点)
	exists后面(相关子查询):表子查询
按结果集的行列数不同:
	标量子查询/单行子查询(结果集只有一行一列)
		一般搭配单行操作符使用:> < >= <= = <>
	列子查询/多行子查询(结果集有一列多行)
		一般搭配多行操作符使用:IN,ANY/SOME,ALL(解释如下图)
	行子查询(结果集有一行多列)
	表子查询(结果集为多行多列)

#1、WHERE或HAVING后面
	#标量子查询:查询谁的工资比 Abel高
	SELECT *
	FROM employees
	WHERE salary > (
			SELECT salary
			FROM employees
			WHERE last_name = 'Abel'
	);
	#列子查询:返回location_id是1400或1700的部门中所有员工姓名
	SELECT last_name
	FROM employees
	WHERE department_id IN(
			SELECT DISTINCT department_id
			FROM departments
			WHERE location_id IN(1400,1700)
	)
	#行子查询:查询员工编号最小并且工资最高的员工信息
	SELECT *
	FROM employees
	WHERE employee_id=(
		SELECT MIN(employee_id)
		FROM employees 
	)
	AND salary=(
		SELECT MAX(salary)
		FROM employees
	)
	上述做法用行子查询:
	SELECT *
	FROM employees
	WHERE (employee_id,salary)=(
		SELECT MIN(employee_id),MAX(salary)
		FROM employees
	);
#2、SELECT后面
	#查询每个部门的员工个数
	SELECT d.*,(
		SELECT COUNT(*)
		FROM employees e
		WHERE e.department_id = d.department_id
	)
	FROM departments d;

#3.FROM后面
	#查询每个部分的平均工资的工资等级
	SELECT a.*,g.grade_level 
	FROM (
		SELECT AVG(salary) ag,department_id
		FROM employees
		GROUP BY department_id
	) AS a
	INNER JOIN job_grades g
	ON a.ag BETWEEN lowest_sal AND highest_sal;

#4、exists后面(相关子查询)
	#查询有员工的部门名
	SELECT department_name
	FROM departments d
	WHERE EXISTS(
		SELECT * 
		FROM employees e
		WHERE d.department_id=e.department_id
	);

在这里插入图片描述

分页查询

应用场景:当要显示的数据一页显示不全,需要分页提交sql请求
语法:
		SELECT 查询列表
		FROM 表
	   【join type】 join 表2
	    on 连接条件
		where 筛选条件
		GROUP BY 分组
		HAVING 筛选条件
		ORDER BY 排序列表 
		limit offset,size;
		offset是要显示条目的起始索引(从0开始,若是0可以省略);sizes是要显示的条目个数

		#有奖金的员工信息,并且工资较高的前10名显示出来
		SELECT * FROM employees WHERE commission_pct IS NOT NULL ORDER BY salary DESC LIMIT 10;

联合查询

	union 联合,合并:将多条查询语句的结果合并成一个结果
	语法:
	查询语句1
	union
	查询语句2
	union
	……
	注意这样写若是多条查询语句中有重复结果会自动去重,若是不想去重需要写union all
	#查询部门编号>90或邮箱包含a的员工信息,可以写成
	SELECT * FROM employees WHERE email LIKE ' %a%' OR department id>90; ;
	利用union
	SELECT * FROM employees WHERE email LIKE '%a%'
	UNION
	SELECT * FROM employees WHERE department_ id>90;
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值