想要成为一名数据研发工程师,SQL是必会的技能。数仓建模过程中用到Hive,其实也是通过写类SQL的语句,通过底层的引擎将其翻译成MapReduce程序,减少了程序员的开发量。除此之外,Spark、Flink等计算框架也支持使用SQL来实现查询。所以在面试的过程中,SQL是必须要考察的内容。今天先分享SQL的基础语法,而窗口函数是重中之重,后面单独写一篇进行讲解。

1.语法

SELECT 查询列表
FROM 表名或视图列表
WHERE 条件表达式
GROUP BY 字段名 HAVING 条件表达式
ORDER BY 字段 ASC|DESC
LIMIT m,n;

说明:

  • 如果SELECT后面是 *,那么表示查询所有字段
  • SELECT后面的查询列表,可以是表中的字段,常量值,表达式,函数
  • 查询的结果是一个虚拟的表
  • select语句,可以包含5种子句:依次是where、 group by、having、 order by、limit必须照这个顺序。

2.关联查询

作用:从2张或多张表中,取出有关联的数据。

关联查询一共有几种情况:

  • 内连接:INNER JOIN 、CROSS JOIN
  • 外连接:左外连接(LEFT OUTER JOIN)、右外连接(RIGHT OUTER JOIN)、全外连接(FULL OUTER JOIN)
  • 自连接:当 table1 和 table2 本质上是同一张表,只是用取别名的方式虚拟成两张表以代表不同的意义

说明:

  • 连接 n 个表,至少需要 n-1 个连接条件。 例如:连接三个表,至少需要两个连接条件。
  • 当两个关联查询的表如果有字段名字相同,并且要查询中涉及该关联字段,那么需要使用表名前缀加以区分
  • 当如果表名比较长时,可以给表取别名,简化 SQL 语句
select <select_list>
from tableA A
inner join tableB B
on A.key=B.key;

select <select_list>
from tableA A
left join tableB B
on A.key=B.key;

select <select_list>
from tableA A
right join tableB B
on A.key=B.key;

select <select_list>
from tableA A
left join tableB B
on A.key=B.key
where B.key is null;

select <select_list>
from tableA A
right join tableB B
on A.key=B.key
where A.key is null;

select <select_list>
from tableA A
left join tableB B
on A.key=B.key
union
select <select_list>
from tableA A
right join tableB B
on A.key=B.key;

select <select_list>
from tableA A
left join tableB B
on A.key=B.key
where B.key is null
union
select <select_list>
from tableA A
right join tableB B
on A.key=B.key
where A.key is null;
2.1 笛卡尔积

定义:将两(或多)个表的所有行进行组合,连接后的行数为两(或多)个表的乘积数。

在 MySQL 中,如果缺少关联条件或者关联条件不准确,则会出现笛卡尔积。

注:外连接必须写关联条件,否则报语法错误。

2.2 关联条件

表连接的约束条件可以有三种方式:WHERE, ON, USING

  • WHERE:适用于所有关联查询。
  • ON:只能和 JOIN 一起使用,只能写关联条件。虽然关联条件可以并到WHERE中和其他条件一起写,但分开写可读性更好。
  • USING:只能和 JOIN 一起使用,而且要求两个关联字段在关联表中名称一致,而且只能表示关联字段值相等。
#关联条件#把关联条件写在where后面
SELECT ename,dname FROM t_employee,t_department WHERE t_employee.dept_id=t_department.did;#把关联条件写在on后面,只能和JOIN一起使用
SELECT ename,dname FROM t_employee JOIN t_department ON t_employee.dept_id=t_department.did;#把关联字段写在using()中,只能和JOIN一起使用
SELECT ename,basic_salary FROM t_employee INNER JOIN t_salary USING(eid);#n张表关联,需要n-1个关联条件
#查询员工姓名,基本工资,部门名称
SELECT ename,basic_salary,dname FROM t_employee,t_department,t_salary
WHERE t_employee.dept_id=t_department.did AND t_employee.eid=t_salary.eid;SELECT ename,basic_salary,dname FROM t_employee JOIN t_department JOIN t_salary
ON t_employee.dept_id=t_department.did AND t_employee.eid=t_salary.eid;
2.3 内连接

有两种,显式的和隐式的,返回连接表中符合连接条件和查询条件的数据行

格式:

隐式:SELECT [cols_list] from 表1,表2 where [condition]

显式:SELECT [cols_list] from 表1 JOIN 表2 ON [关联条件] where [其他筛选条件]

SELECT dep.dept_id,dep.name,emp.id,emp.name
FROM t_employee emp JOIN t_department dep
ON emp.dept_id=dep.dept_id;

2.4 外连接

外连接分为左外连接,右外连接,

  • 左外连接(LEFT OUTER JOIN),简称左连接(LEFT JOIN)

#查询所有部门信息以及该部门员工信息
SELECT did,dname,eid,ename
FROM t_department LEFT OUTER JOIN t_employee
ON t_department.did = t_employee.dept_id;

  • 右外连接(RIGHT OUTER JOIN),简称右连接(RIGHT JOIN)

#查询所有员工信息,以及员工的部门信息
SELECT eid,ename,did,dname
FROM t_department RIGHT OUTER JOIN t_employee
ON t_employee.dept_id = t_department.did;

  • 全外连接(FULL OUTER JOIN),简称全连接(FULL JOIN)。MySQL 不支持 FULL JOIN,但是可以用 left join union right join代替。

#查询所有部门信息和员工信息
SELECT did,dname,eid,ename
FROM t_department LEFT OUTER JOIN t_employee
ON t_department.did = t_employee.dept_id
UNION
SELECT did,dname,eid,ename
FROM t_department RIGHT OUTER JOIN t_employee
ON t_department.did = t_employee.dept_id;

2.5 自连接

当 table1 和 table2 本质上是同一张表,只是用取别名的方式虚拟成两张表以代表不同的意义。然后两个表再进行内连接,外连接等查询。

#自连接#查询员工姓名以及领导姓名,仅显示有领导的员工
SELECT emp.ename,mgr.ename
FROM t_employee AS emp, t_employee AS mgr
WHERE emp.mid = mgr.eid;#查询员工姓名以及领导姓名,仅显示有领导的员工
SELECT emp.ename,mgr.ename
FROM t_employee AS emp JOIN t_employee AS mgr
ON emp.mid = mgr.eid;#查询所有员工姓名及其领导姓名
SELECT emp.ename,mgr.ename
FROM t_employee AS emp LEFT JOIN t_employee AS mgr
ON emp.mid = mgr.eid;

3.select 的五个子句

3.1 where 条件查询

设置条件,对记录进行筛选。例如查询id=1的学生信息:

select * from stu_tb where id=1;
3.2 group by 分组查询

很多情况下,用户都需要进行一些汇总操作,比如统计整个公司的人数或者统计每一个部门的人数等。在分组之后,由于一个分组有多行数据,所以必须要进行聚合才能得到1对1的答案进行输出。聚合函数有如下几种:

  • AVG(【DISTINCT】 expr):返回 expr 的平均值
  • COUNT(【DISTINCT】 expr):返回 expr 的非NULL值的数目
  • MIN(【DISTINCT】 expr):返回 expr 的最小值
  • MAX(【DISTINCT】 expr):返回 expr 的最大值
  • SUM(【DISTINCT】 expr):返回 expr 的总和
#聚合函数#AVG(【DISTINCT】 expr) 返回expr的平均值
SELECT AVG(basic_salary) FROM t_salary;#COUNT(【DISTINCT】 expr)返回expr的非NULL值的数目
#统计员工总人数
SELECT COUNT(*) FROM t_employee;#count(*)统计的是记录数
#统计员工表的员工所在部门数
SELECT COUNT(dept_id) FROM t_employee;#统计的是非NULL值
SELECT COUNT(DISTINCT dept_id) FROM t_employee;#统计的是非NULL值,并且去重#MIN(【DISTINCT】 expr)返回expr的最小值
#查询最低基本工资值
SELECT MIN(basic_salary) FROM t_salary;#MAX(【DISTINCT】 expr)返回expr的最大值
#查询最高基本工资值
SELECT MAX(basic_salary) FROM t_salary;#查询最高基本工资与最低基本工资的差值
SELECT MAX(basic_salary)-MIN(basic_salary) FROM t_salary;#SUM(【DISTINCT】 expr)返回expr的总和
#查询基本工资总和
SELECT SUM(basic_salary) FROM t_salary;

上面的聚合函数是对整个表格使用的。如果加上 group by,可以实现按照部门统计等操作。

#group by + 聚合函数#统计每个部门的人数
SELECT dept_id,COUNT(*) FROM t_employee
GROUP BY dept_id;#统计每个部门的平均基本工资
SELECT emp.dept_id,AVG(s.basic_salary )
FROM t_employee AS emp,t_salary AS s
WHERE emp.eid = s.eid
GROUP BY emp.dept_id;#统计每个部门的年龄最大者
SELECT dept_id,MAX(birthday) FROM t_employee GROUP BY dept_id;#统计每个部门基本工资最高者
SELECT emp.dept_id,MAX(s.basic_salary )
FROM t_employee AS emp,t_salary AS s
WHERE emp.eid = s.eid
GROUP BY emp.dept_id;#统计每个部门基本工资之和
SELECT emp.dept_id,SUM(s.basic_salary )
FROM t_employee AS emp,t_salary AS s
WHERE emp.eid = s.eid
GROUP BY emp.dept_id;

注意:

  • 用 count(*),count(1) 谁好呢?其实,对于 MyISAM引擎的表,没有区别的。这种引擎内部有一计数器在维护着行数。对于 InnoDB 的表,用 count(*) 直接读行数,效率很低,因为 InnoDB 真的要去数一遍。
  • 在SELECT 列表中所有未包含在组函数中的列都应该是包含在 GROUP BY 子句中的,换句话说,SELECT列表中最好不要出现GROUP BY子句中没有的列。
3.3 having 筛选

having与where类似,可筛选数据。但也有不同点,不同点如下:

  • where 针对表中的列发挥作用,查询数据;having 针对查询结果中的列发挥作用,筛选数据
  • where 后面不能写分组函数,而 having 后面可以使用分组函数
  • having 只用于 group by 分组统计语句
#按照部门统计员工人数,仅显示部门人数少于3人的
SELECT dept_id,COUNT(*) AS c
FROM t_employee
WHERE dept_id IS NOT NULL
GROUP BY dept_id
HAVING c <3;
3.4 order by 排序

按一个或多个字段对查询结果进行排序。用法:order by col1,col2,col3…

  • 先按col1排序如果col1相同就按照col2排序,依次类推。
  • col1,col2,col3可以是select后面的字段也可以不是。
  • 默认是升序,也可以在字段后面加asc显示说明是升序,desc为降序。
  • order by 后面除了跟1个或多个字段,还可以写表达式,函数,别名等。
#统计每个部门的平均基本工资,并按照平均工资降序排列
SELECT emp.dept_id,AVG(s.basic_salary)
FROM t_employee AS emp,t_salary AS s
WHERE emp.eid = s.eid
GROUP BY emp.dept_id
ORDER BY AVG(s.basic_salary) DESC;
3.5 limit 分页

用法:limit m,n

  • m 表示从下标为 m 的记录开始查询,第一条记录下标为 0
  • n 表示取出 n 条出来,如果从 m 开始不够 n 条了,就有几条取几条。
  • m=(page-1)*n,page 是页码,n 表示每页显示的条数。例如:第一页limit 0,n。第二页limit n,n。依次类推,得出公式limit (page-1)*n , n
#统计每个部门的平均基本工资,并显示前三名
SELECT emp.dept_id,AVG(s.basic_salary)
FROM t_employee AS emp,t_salary AS s
WHERE emp.eid = s.eid
GROUP BY emp.dept_id
ORDER BY AVG(s.basic_salary) DESC
LIMIT 0,3;

4.子查询

某些情况下,当进行一个查询时,需要的条件或数据要用另外一个 select 语句的结果,这个时候,就要用到子查询。例如求比张三工资高的员工。一般根据子查询的嵌入位置分为,where型子查询,from型子查询,exists型子查询。

4.1 where 型子查询

where 型子查询即把内层 sql 语句查询的结果作为外层 sql 查询的条件。

  • 子查询要包含在括号内。

  • 建议将子查询放在比较条件的右侧。

  • 单行操作符对应单行子查询,多行操作符对应多行子查询。

    • 对于单行操作符,右边子查询必须返回的是单个值,单行比较运算符(=,>,>=,<,<=,<>)

    • 对于多行操作符,右边子查询可以返回多行,但必须是单列,ALL,ANY,IN 其中,ALL和ANY运算符必须与单行比较运算符(=,>,>=,<,<=,<>)结合使用。

      • IN:等于任何一个

      • ALL:和子查询返回的所有值比较。例如:sal>ALL(1,2,3) 等价于 sal>1 && sal>2 &&sal>3,即大于所有。

      • ANY:和子查询返回的任意一个值比较。例如:sal>ANY(1,2,3)等价于sal>1 or sal>2 or sal>3,即大于任意一个就可以。

      • EXISTS:判断子查询是否有返回结果(不关心具体行数和内容),如果返回则为TRUE,否则为FALSE。

#查询和张三,李四在同一个部门的员工
SELECT * FROM t_employee
WHERE dept_id IN(SELECT dept_id FROM t_employee WHERE ename='张三' OR ename = '李四');#查询全公司工资最高的员工编号,基本工资
#方法一
SELECT eid,basic_salary FROM t_salary
WHERE basic_salary = (SELECT MAX(basic_salary) FROM t_salary);
#方法二
SELECT eid,basic_salary FROM t_salary
WHERE basic_salary >= ALL(SELECT basic_salary FROM t_salary);
4.2 from 型子查询

from 型子查询即把内层 sql 语句查询的结果作为临时表供外层 sql 语句再次查询。

#找出比部门平均工资高的员工编号,基本工资
SELECT t_employee.eid,basic_salary
FROM t_salary INNER JOIN t_employee INNER JOIN (SELECT emp.dept_id AS did,AVG(s.basic_salary) AS avg_salaryFROM t_employee AS emp,t_salary AS sWHERE emp.eid = s.eidGROUP BY emp.dept_id) AS temp
ON t_salary.eid = t_employee.eid AND t_employee.dept_id = temp.did
WHERE t_salary.basic_salary > temp.avg_salary;
4.3 exists 型子查询

exists 型子查询把外层的查询结果拿到内层,看内层的查询是否成立。

#查询部门信息,该部门必须有员工
SELECT * FROM t_department
WHERE EXISTS (SELECT * FROM t_employee WHERE t_employee.dept_id = t_department.did);

欢迎关注公众号。

【SQL】SQL的基础语法相关推荐

  1. HiveQL学习笔记(二):Hive基础语法与常用函数

    本系列是本人对Hive的学习进行一个整理,主要包括以下内容: 1.HiveQL学习笔记(一):Hive安装及Hadoop,Hive原理简介 2.HiveQL学习笔记(二):Hive基础语法与常用函数 ...

  2. SQLServer基础语法大全(基础篇)

    SQLServer基础语法 一.插入语句 1. 普通插入 2. 表数据查询(复制)插入 二.查询语句 1. 所有数据查询 2. 根据某条件查询前多少条数据 三.更新语句 1. 单表数据更新 2. 多表 ...

  3. SQL基础语法学习总结

    本篇博客对于sql的基础语法做一个总结,学的东西太多太杂,总是不能记住太多东西,所以很多东西,会用,但是背不下来,毕竟不可能把所有语法和关键字都背完啊,本篇文章呢就用通俗易懂的话做一个基础知识的总结. ...

  4. SQL语句基础语法——简单的增,删,查,改

           SQL语句全称为Structured Query Language,翻译为结构化查询语句,是面向数据库的语句.但是不同的数据库会有一些出入,使用数据库时应阅读相应的数据库手册.      ...

  5. Oracle PL/SQL基础语法学习13:比较运算符

    系列文章目录 Oracle PL/SQL基础语法学习12:短路求值 Oracle PL/SQL基础语法学习13:比较运算符 Oracle PL/SQL基础语法学习14:BOOLEAN表达式 文章目录 ...

  6. sql server基础语法 创建数据库 创建表

    sql server基础语法 创建数据库 创建表 1.创建数据库 2.表的创建 3.在现有表中添加标识列 4.创建外键 5.添加外键 6.约束 7.创建局部临时表 8.创建全局临时表 9.创建具有ch ...

  7. sql 2005基础语法总结

    sql 2005基础语法总结 目录 基础查询... 4 Select语句查询.... 4 1.查询单列数据... 4 2查询所用列数据... 4 3.查询指定的列数据... 4 4.在查询时使用别名. ...

  8. mysql安装及sql基础语法

    卑微小吴励志写博客第五天 由于国际形式紧张,某为公司今年很多项目的最紧急的事情就是数据库迁移,基本上都是从oracle迁移到mysql.所以对于程序员的我们,学习mysql数据库的相关知识是必须的.而 ...

  9. hive sql练习_SQL语句+语法 I 数据分析面试必备

    - 点击上方"中国统计网"订阅我吧!- 前些天在网上冲浪的时候看到一个案例咨询,问说世界500强的数据分析要不要去,评论区一片爆炸:"楼主能分享一下文科生怎么转行做数据分 ...

  10. sql server T-SQL 基础

    SQL语言按照用途可以分为如下3类: ①DDL(Data Definition Language)  数据定义语言: 定义修改和删除数据库.表.索引和视图等 ②DML(Data Manipulatio ...

最新文章

  1. 模具和java哪个好_93年,本科毕业一年(模具专业),想学Java转行怎么样?
  2. 人工智能及其应用(第5版).蔡自兴-4章课后习题。【部分参考答案】
  3. Hadoop的调度器总结
  4. modelsim仿真中遇到的问题
  5. 使用Http-Repl工具测试ASP.NET Core 2.2中的Web Api项目
  6. 使用Apache Lucene 4.3轻松进行搜索
  7. mysql并发获取唯一数值_高并发分布式环境中获取全局唯一ID[分布式数据库全局唯一主键生成]...
  8. 飞鸽传书2011绿色版使用简介
  9. 微型计算机d3000,13级仪表微机重点教程.doc
  10. 【leetcode】1041. Robot Bounded In Circle
  11. 测试用例方法-等价类划分
  12. 自动更新纯真IP数据库
  13. 有限温度量子多体系统与热态张量网络
  14. VLOOKUP多条件匹配
  15. cpu怎么开启php,win10开启cpu虚拟化的方法
  16. vue-element-admin的二次开发
  17. 想要改变客户态度 这些销售话术需掌握
  18. UCSC genome browser 个人track 安装
  19. android WIFI学习总结
  20. localhost是什么?

热门文章

  1. abaqus -复合材料
  2. hg8120c 维修使能工具_ONT 用户手册(中国移动) V300R016C10.doc
  3. python 网络调试助手
  4. MCU学习笔记_UPF
  5. android 开源 音乐播放器,Android 开源在线音乐播放器
  6. Android颜色选择器
  7. canbus是什么意思_canbus.是什么意思
  8. 字节跳动笔试题-前端(互娱)
  9. pycharm搜索不到安装包
  10. 动态磁盘与基本磁盘的相互转换