面试题

经典50题图解:https://zhuanlan.zhihu.com/p/38354000

单表基本查询

登录

  1. -- 做登录验证:查询user表中用户为admin、密码为123456的用户
  2. -- 查得到就有一条结果数据,查不到就是错误密码或用户名不存在
  3. select * from company.`user`
  4. WHERE loginId = 'admin' AND loginPwd = '123123';

image.png

翻页数据查询

获取员工数据,按照入职时间降序,并且分页数据为第二页(每页10条)

  1. select * from company.employee
  2. ORDER BY employee.joinDate DESC
  3. LIMIT 10,10

image.png
image.png

查询-工资最高的女员工

  1. select *,
  2. CASE employee.ismale
  3. WHEN 0
  4. THEN '女'
  5. END sex
  6. from company.employee
  7. WHERE employee.ismale = 0
  8. ORDER BY employee.salary DESC
  9. LIMIT 0, 1

image.png
image.png

联表查询

笛卡尔积

解释

获取出来的表,表现形式上是两个表的表头相乘。看下边的例子解释:
表一:
image.png
表二:
image.png
笛卡尔积结果:观察结果表,可以发现,是company的每一行,乘以user的每一行得到的结果。
image.png
连接示意图:
拿出user表的第一行,对应company的每一行。拿出user表的第二行,对应company的每一行。拿出user表的第三行,对应company的每一行。知道user表每一行都拿完,得到最终结果。
感觉像是两层for循环得到的九九乘法表的结果。
image.png

三表的笛卡尔积联表查询

再加一个表,查询顺序和结果会是怎样呢?下图,加一个表三(学生表)
image.png
执行结果如下:
image.png

做题:创建一张表,记录足球队。查询出对阵表。

image.png
输出对阵信息:各个队除了自己以外,和其他队都比赛一次
image.png赋值一张表
查询语句:

  1. SELECT football_team_copy1.name AS 'guest',football_team.name AS 'master' -- 将结果表的列数据修改
  2. FROM `football_team`,football_team_copy1
  3. -- 拿到两个表的笛卡尔积结果
  4. WHERE football_team.name != football_team_copy1.name
  5. -- 过滤掉自己和自己对打的数据

查询结果:
image.png

用同一张表做笛卡尔积——通过给表定义别名实现

  1. SELECT football_team_copy.name AS 'guest',football_team.name AS 'master'
  2. FROM football_team,football_team AS football_team_copy -- 定义别名football_team_copy,然后使用
  3. WHERE football_team.name != football_team_copy.name

左连接,左外连接, left join

以其中一张表为基准,去连接另一张表。每次连接的时候判断条件是否满足。
学习了左连接,就会了右连接。

写法:

  1. SELECT * FROM department AS d LEFT JOIN employee AS e
  2. ON d.id = e.deptId
  3. -- 连接方法:把department部门表的每一行依次拿出来,然后每次拿当前行与employee表的每一行进行对比,当前行的ide表中对应行的deptId一致就生成结果表的一行。
  4. -- 像是两个数组的嵌套循环

image.png
类似效果:

  1. arr = ['a', 'b', 'c']
  2. arr1 = ['d', 'e', 'f']
  3. for(var i=0; i < arr.length; i++){
  4. for(var j=0; j < arr1.length; j++){
  5. return arr[i] = arr1[i]
  6. }
  7. }

左连接特点:ON条件不成立,导致数据连接失败的时候

以左表为基准,如果不满足条件,左表至少出现一次。
image.png

右连接,右外连接,right join

写法同左连接。结果相反
image.png

  1. SELECT * FROM employee AS e RIGHT JOIN department AS d
  2. ON d.id = e.deptId
  3. ORDER BY d.id DESC
  4. -- 反过来写,以右边为基准。如果右表满足不了条件,则右表至少出现一行。(这里右表是department

内连接,inner join 【常用】

两个表的on条件必须满足,才会生成结果表。不满足的就不会出现

  1. SELECT * FROM employee AS e INNER JOIN department AS d
  2. ON d.id = e.deptId
  3. ORDER BY d.id DESC

连接多个表

  1. SELECT * FROM employee AS e INNER JOIN department AS d INNER JOIN company AS c -- 连接了三个表
  2. ON d.id = e.deptId AND c.id < 2 -- 同时卡了两个条件
  3. ORDER BY d.id DESC - 对结果进行排序
  4. -- 上边的写法改造如下:
  5. SELECT *
  6. FROM employee AS e
  7. INNER JOIN department AS d ON d.id = e.deptId
  8. INNER JOIN company AS c ON c.id < 2
  9. ORDER BY d.id DESC

题目

联表查询指定字段,并将外键显示为外键对应主键的name

显示出所有员工的姓名、性别(使用男或女表示)、入职时间、薪水、所属部门(显示部门名称)、所属公司(显示公司名称)

  1. SELECT e.`name`,
  2. CASE e.ismale -- 将性别数据处理,判断条件展示中文中文
  3. WHEN 1 THEN
  4. '女'
  5. ELSE
  6. '男'
  7. END sex,
  8. c.`name` AS '公司名称', -- 将公司名称列进行处理,起别名展示
  9. d.`name` AS '部门名称',
  10. e.joinDate,
  11. e.salary
  12. FROM employee AS e
  13. INNER JOIN department AS d ON e.deptId = d.id -- 联部门表,找出当前人的外键deptId与部门表中主键id一致的那条数据
  14. INNER JOIN company AS c ON d.companyId = c.id -- 继续,联公司表,找出当前部门的外键deptId与公司表中主键id一致的那条数据

联表查询并过滤数据

查询腾讯和蚂蚁金服的所有员工姓名、性别、入职时间、部门名、公司名

  1. SELECT e.`name`,
  2. CASE e.ismale
  3. WHEN 1 THEN
  4. '女'
  5. ELSE
  6. '男'
  7. END sex,
  8. c.`name` AS '公司名称',
  9. d.`name` AS '部门名称',
  10. e.joinDate
  11. FROM employee AS e
  12. INNER JOIN department AS d ON e.deptId = d.id
  13. INNER JOIN company AS c ON d.companyId = c.id
  14. -- 第一种,模糊匹配的写法
  15. WHERE c.name LIKE '腾讯%' OR c.name LIKE '蚂蚁%' -- 模糊匹配要用like关键字
  16. -- 最后一句,或者用下边IN的写法,需要精确匹配
  17. WHERE c.name IN ('腾讯科技','蚂蚁金服')

联表查询并过滤数据

查询渡一教学部的所有员工姓名、性别、入职时间、部门名、公司名

  1. SELECT e.`name`,
  2. CASE e.ismale
  3. WHEN 1 THEN
  4. '女'
  5. ELSE
  6. '男'
  7. END sex,
  8. c.`name` AS '公司名称',
  9. d.`name` AS '部门名称',
  10. e.joinDate
  11. FROM employee AS e
  12. INNER JOIN department AS d ON e.deptId = d.id
  13. INNER JOIN company AS c ON d.companyId = c.id
  14. WHERE c.name LIKE '渡一%' AND d.name = '教学部'

联表查询并去重

列出所有公司员工居住的地址(要去掉重复数据处理)

  1. SELECT DISTINCT e.location FROM employee AS e