复习
describe parking_records
# 查表中的的所有字段
select * from parking_records
# 查不重复的车牌号码
select distinct `车牌` from parking_records
# 着重号的使用
select parking_records.`停车时长(小时)`, parking_records.`优惠金额` from parking_records
# where语句的使用
select parking_records.`车牌` from parking_records where parking_records.`优惠金额` > 10
# 排序
select parking_records.`车牌` from parking_records where parking_records.`入场时间` > 1 order by parking_records.`停车时长(小时)` asc
# 解决笛卡尔异常
select student.student_name , score.score from student , score where student.student_id= score.student_id
# 等值连接
select student.student_name , score.score from student join score on student.student_id=score.student_id
# 非等值连接
select student.student_name , score.score from student join score on student.student_id=score.student_id where score.score between 70 and 90
# 自链接
-- 自连接student表,查询每个学生的姓名和其对应的班长姓名
SELECT
stu.student_id AS student_id, -- 学生学号(别名语义匹配)
stu.student_name AS student_name, -- 学生姓名
monitor.student_id AS monitor_id, -- 班长学号
monitor.student_name AS monitor_name -- 班长姓名
FROM
student stu -- 别名stu:代表普通学生
INNER JOIN
student monitor -- 别名monitor:代表班长(自连接的另一张"班长表")
ON
stu.monitor_id = monitor.student_id; -- 核心关联条件:学生的班长ID = 班长的学生ID
面试题一
主键可以唯一标识一条记录,用来确保数据的完整性,一个表只能有一个主键
外键就是此表引用其余表的主键,可以为空,可以重复,用来和其他表建立联系
索引就是用来将数据库拆分快速查询的工具,主键天然具有索引,一个表具有多个索引,一个索引只有不重复的字段
面试题二
select 语句 :指定要查询的列(可以是字段、表达式、聚合函数等),是最终返回结果的定义。
from语句:指定查询的数据源表(可以是单表、多表、子查询结果等)。
where语句:在分组之前对行数据进行过滤,仅保留满足条件的行
group by 语句:对查询结果按指定列进行分组,通常配合聚合函数(如COUNT()、SUM())使用。
having语句:在分组之后对分组结果进行过滤,仅保留满足条件的分组(可以使用聚合函数作为条件)。
order by 语句:对最终查询结果按指定列进行升序 / 降序排序
limit 语句:限制返回结果的行数(常用于分页场景)
面试题三
-
FROM:先确定要查询的数据源,加载表数据。 -
WHERE:从数据源中过滤出符合条件的行数据。 -
GROUP BY:将过滤后的行按指定列分组。 -
HAVING:对分组后的结果再进行过滤,淘汰不符合条件的分组。 -
SELECT:从最终的分组 / 行数据中选择需要的列(这一步才会生成最终的结果集)。 -
ORDER BY:对SELECT生成的结果集进行排序。 -
LIMIT:对排序后的结果集进行行数限制,返回最终结果
面试题四
一、DISTINCT 去重
-
作用:对查询结果集的所有字段进行整体去重,返回唯一的记录行。
-
语法示例: -- 单列去重 SELECT DISTINCT department FROM employees;
-- 多列去重(只有所有字段值都相同时才视为重复) SELECT DISTINCT department, position FROM employees;
二、GROUP BY 去重
-
作用:通过分组将重复行合并为一组,既可以实现去重,也可以配合聚合函数进行统计。
-
语法示例: -- 单列去重(和DISTINCT效果类似) SELECT department FROM employees GROUP BY department;
三、ROW_NUMBER() OVER() 窗口函数去重
- 作用:为重复的行分配唯一序号,结合
WHERE筛选出序号为 1 的行,实现精准去重(可自定义保留哪一行)。 - 语法示例: -- 保留每个部门中薪资最高的员工(按薪资降序,取第一行) SELECT emp_id, name, department, salary FROM ( SELECT emp_id, name, department, salary, ROW_NUMBER() OVER ( PARTITION BY department -- 按部门分组去重 ORDER BY salary DESC -- 组内按薪资降序排序 ) AS rn FROM employees ) AS temp WHERE rn = 1; -- 仅保留每组
单行函数
对数据表中的每一行数据独立进行计算,每一行都会返回一个对应的结果值。
数值和字符串函数
ABS()(绝对值)、ROUND()(四舍五入)、MOD()(取模)、CEIL()(向上取整)、FLOOR()(向下取整)。
CONCAT()(拼接)、LENGTH()(长度)、UPPER()(转大写)、LOWER()(转小写)、SUBSTR()(截取)。
日期和时间函数
NOW()(当前时间)、DATE_FORMAT()(日期格式化)、YEAR()/MONTH()/DAY()(提取年 / 月 / 日)、DATEDIFF()(日期差)。
流程控制和加解密函数
IF()(简单条件)、CASE WHEN(复杂条件)、IFNULL()(处理 NULL 值)。
-- 创建员工表(如果表已存在则先删除,新手测试用,生产环境慎用DROP)
DROP TABLE IF EXISTS employees;
CREATE TABLE employees (
emp_id INT PRIMARY KEY COMMENT '员工ID(主键)',
emp_name VARCHAR(20) NOT NULL COMMENT '员工姓名',
dept_id INT COMMENT '部门ID',
salary DECIMAL(10,2) NOT NULL COMMENT '月薪(保留2位小数)',
hire_date DATE NOT NULL COMMENT '入职日期',
bonus DECIMAL(10,2) COMMENT '奖金(允许NULL)'
) COMMENT '员工信息表';
-- 插入示例数据(和之前示例中的数据完全一致)
INSERT INTO employees (emp_id, emp_name, dept_id, salary, hire_date, bonus)
VALUES
(1, '张三', 10, 8000.00, '2020-05-10', NULL),
(2, '李四', 10, 9500.00, '2019-08-15', 2000.00),
(3, '王五', 20, 7500.00, '2021-03-20', 1500.00),
(4, '赵六', 20, 10000.00, '2020-11-05', 3000.00),
(5, '孙七', 10, 8500.00, '2022-01-18', 1000.00);
# 数值函数
select employees.emp_name,
employees.salary,
employees.bonus,
IFNULL(employees.bonus,0) as bonus_fix,
ROUND(salary,-3) as salary_round,
salary * 12 + IFNULL(employees.bonus,0) year_salary
from employees
select concat (emp_name,'_',dept_id) as emp_dept,
upper(emp_name) as name_upper,
year(employees.hire_date) as hire_data,
DATEDIFF(NOW(), hire_date) AS days_since_hire
from employees
SELECT
emp_name,
salary,
CASE
WHEN salary < 8000 THEN '低'
WHEN salary BETWEEN 8000 AND 10000 THEN '中'
ELSE '高'
END AS salary_level
FROM employees;
聚合函数
聚合函数是 MySQL 中用于对一组数据进行汇总计算,并返回单个结果值的函数
常见函数
核心函数:COUNT()、SUM()、AVG()、MAX()、MIN()、GROUP_CONCAT()
GROUP BY
这是实现 “分组聚合” 的核心语法,用于将数据按指定字段分组,再对每组单独做聚合计算
HAVING
用于对聚合后的结果进行筛选,与WHERE的核心区别在于作用阶段不同。
- WHERE:作用于原始数据行,筛选条件不能用聚合函数;
- HAVING:作用于分组聚合后的结果,筛选条件可以用聚合函数(或聚合别名)。
SELECT
dept_id,
COUNT(*) AS emp_count, -- 统计每组人数
AVG(salary) AS avg_salary, -- 每组平均工资
MAX(salary) AS max_salary -- 每组最高工资
FROM employees
GROUP BY dept_id; -- 按部门分组
SELECT
dept_id,
COUNT(*) AS emp_count,
AVG(salary) AS avg_salary
FROM employees
WHERE YEAR(hire_date) >= 2020 ; -- 先筛选:只保留2020年及以后入职的员工(聚合前)
GROUP BY dept_id
HAVING avg_salary > 8000; -- 后筛选:只保留平均工资>8000的部门(聚合后)