AI + 数据库(第二天)

11 阅读6分钟

复习

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的部门(聚合后)

面试题

image.png

image.png

image.png