分组后只能查询分组的列和聚合列

  1. GROUP BY 按照什么分组

运行顺序

运行顺序从高到低
image.png

HAVING 相当于 WHERE 只是运行顺序不一样

练习

  1. -- 查询员工分布的居住地,以及每个居住地有多少名员工
  2. -- 天府三街 3
  3. SELECT location, count(id) as empnumber
  4. FROM employee
  5. GROUP BY location
  6. HAVING empnumber>=40
  1. -- 查询所有薪水在10000以上的员工的分布的居住地,然后仅得到聚集地大于30的结果
  2. SELECT location, count(id) as empnumber
  3. FROM employee
  4. WHERE salary>=10000
  5. GROUP BY location
  6. HAVING count(id)>=30

子查询

练习题第三题第六题都用到啦子查询

什么是子查询

子查询就是将上次查询结果作为表继续查询

示例

  1. -- 查询所有公司10年内入职的居住在万家湾的女员工数量
  2. SELECT
  3. c.`name`,
  4. CASE
  5. WHEN r.number IS NULL THEN
  6. 0
  7. ELSE
  8. 1
  9. END number
  10. FROM
  11. company AS c
  12. LEFT JOIN (
  13. SELECT
  14. c.id,
  15. c.`name`,
  16. COUNT( e.id ) AS number
  17. FROM
  18. employee AS e
  19. INNER JOIN department AS d ON d.id = e.deptId
  20. INNER JOIN company AS c ON c.id = d.companyId
  21. WHERE
  22. TIMESTAMPDIFF(
  23. YEAR,
  24. e.joinDate,
  25. CURDATE()) <= 8
  26. AND e.location LIKE '%万家湾%'
  27. AND e.ismale = 0
  28. GROUP BY
  29. c.id,
  30. c.`name`
  31. ) AS r ON c.id = r.id

image.png
中的子查询为

  1. -- 查询 入职10年内且居住万家湾的女员工的数量然后按照公司名分组
  2. (
  3. SELECT
  4. c.id,
  5. c.`name`,
  6. COUNT( e.id ) AS number
  7. FROM
  8. employee AS e
  9. INNER JOIN department AS d ON d.id = e.deptId
  10. INNER JOIN company AS c ON c.id = d.companyId
  11. WHERE
  12. TIMESTAMPDIFF(
  13. YEAR,
  14. e.joinDate,
  15. CURDATE()) <= 8
  16. AND e.location LIKE '%万家湾%'
  17. AND e.ismale = 0
  18. GROUP BY
  19. c.id,
  20. c.`name`
  21. ) AS r

image.png只显示出有员工数量的,没有员工达到要求的没有显示,题意要求的所有公司,那吗就要在这个查询的基础上进行左连接

练习题

  1. -- 查询所有薪水在10000以上的员工的分布的居住地,然后仅得到聚集地大于30的结果
  2. SELECT location, count(id) as empnumber
  3. FROM employee
  4. WHERE salary>=10000
  5. GROUP BY location
  6. HAVING count(id)>=30
  1. -- 2. 查询每个公司的员工数量
  2. SELECT c.`name`, COUNT(e.id) as number
  3. FROM company as c INNER JOIN department as d on c.id = d.companyId
  4. INNER JOIN employee as e on d.id = e.deptId
  5. GROUP BY c.id, c.`name`
  1. -- 查询所有公司10年内入职的居住在万家湾的女员工数量
  2. SELECT
  3. c.`name`,
  4. CASE
  5. WHEN r.number IS NULL THEN
  6. 0
  7. ELSE
  8. 1
  9. END number
  10. FROM
  11. company AS c
  12. LEFT JOIN (
  13. SELECT
  14. c.id,
  15. c.`name`,
  16. COUNT( e.id ) AS number
  17. FROM
  18. employee AS e
  19. INNER JOIN department AS d ON d.id = e.deptId
  20. INNER JOIN company AS c ON c.id = d.companyId
  21. WHERE
  22. TIMESTAMPDIFF(
  23. YEAR,
  24. e.joinDate,
  25. CURDATE()) <= 8
  26. AND e.location LIKE '%万家湾%'
  27. AND e.ismale = 0
  28. GROUP BY
  29. c.id,
  30. c.`name`
  31. ) AS r ON c.id = r.id
  1. -- 4. 查询渡一所有员工分布在哪些居住地,每个居住地的数量
  2. SELECT e.location, count(e.id) as empnumber
  3. FROM company as c INNER JOIN department as d on c.id = d.companyId
  4. INNER JOIN employee as e on d.id = e.deptId
  5. WHERE c.`name` LIKE '%渡一%'
  6. GROUP BY e.location
  1. -- 5. 查询员工人数大于200的公司信息
  2. SELECT * FROM company
  3. WHERE id in (
  4. SELECT c.id
  5. FROM company as c INNER JOIN department as d on c.id = d.companyId
  6. INNER JOIN employee as e on d.id = e.deptId
  7. GROUP BY c.id, c.`name`
  8. HAVING count(e.id)>=200
  9. )
  1. -- 6. 查询渡一公司里比它平均工资高的员工
  2. SELECT e.*
  3. FROM company as c INNER JOIN department as d on c.id = d.companyId
  4. INNER JOIN employee as e on d.id = e.deptId
  5. WHERE c.`name` LIKE '%渡一%' AND
  6. e.salary>(
  7. -- 查询渡一的平均薪资
  8. SELECT avg(e.salary)
  9. FROM company as c INNER JOIN department as d on c.id = d.companyId
  10. INNER JOIN employee as e on d.id = e.deptId
  11. WHERE c.`name` LIKE '%渡一%'
  12. )
  1. -- 7. 查询渡一所有名字为两个字和三个字的员工对应人数
  2. SELECT CHAR_LENGTH(e.`name`) as 姓名长度, COUNT(E.ID) as 员工数量
  3. FROM company as c INNER JOIN department as d on c.id = d.companyId
  4. INNER JOIN employee as e on d.id = e.deptId
  5. WHERE c.`name` LIKE '%渡一%'
  6. GROUP BY CHAR_LENGTH(e.`name`)
  7. HAVING 姓名长度 in (2,3)
  1. -- 8. 查询每个公司每个月的总支出薪水,并按照从低到高排序
  2. SELECT c.`name`, SUM(e.salary) as sumofsalary
  3. FROM company as c INNER JOIN department as d on c.id = d.companyId
  4. INNER JOIN employee as e on d.id = e.deptId
  5. GROUP BY c.id, c.`name`
  6. ORDER BY sumofsalary