炼码LintCode--数据库题库(级别:简单;数量:55道)--刷题笔记_02

news2024/11/18 17:23:17

目录

  • 炼码LintCode--数据库题库(级别:简单;数量:55道)--刷题笔记_02
    • 3618 · 耗时前三的任务(日期差)
      • 题:
      • sql:
      • 解释:
        • DATEDIFF 天数差
        • order by 别名
        • TIMESTAMPDIFF 月、年差
    • 3616 · 整合成绩单
      • 题:
      • sql:
    • 3614 · 查询客户的推荐人
      • 题:
      • sql:
    • 3613 · 查询成绩排名在第二到第五的学生
      • 题:
      • sql:
      • 解释
        • ROW_NUMBER() 开窗函数排序
        • limit
    • 3610 · 所有学生都选修的课程
      • 题:
      • sql:
      • 解释
        • having、count、distinct
    • 3607 · 考试通过的人数
      • 题:
      • sql:
      • 解释
        • sum 数值和表达式区分
    • 3501 · 最棒的销售
      • 题:
      • sql:
      • 解释
    • 2812 · 存储过程变量(一)
      • 题:
      • sql:
      • 解释
    • 2811 · 存储过程 INOUT 参数(二)
      • 题:
      • sql:
      • 解释
    • 2810 · 存储过程 INOUT 参数(一)
      • 题:
      • sql:
    • 2809 · 存储过程 OUT 参数(二)
      • 题:
      • sql:
      • 解释
    • 2808 · 存储过程 OUT 参数(一)
      • 题:
      • sql:
    • 2807 · 存储过程 IN 参数(二)
      • 题:
      • sql:
    • 2806 · 存储过程 IN 参数(一)
      • 题:
      • sql:
    • 2802 · 删除存储过程(二)
      • 题:
      • sql:
    • 2801 · 删除存储过程(一)
      • 题:
      • sql:
    • 2761 · 认识存储过程(二)
      • 题:
      • sql:
    • 2760 · 认识存储过程(一)
      • 题:
      • sql:
    • 2725 · 视图的本地检查
      • 题:
      • sql:
    • 2724 · 视图的级联检查
      • 题:
      • sql:
    • 2723 · 显示一个视图的定义
      • 题:
      • sql:
    • 2721 · 创建一个确保一致性的视图(二)
      • 题:
      • sql:
    • 2720 · 创建一个确保一致性的视图(一)
      • 题:
      • sql:
    • 2716 · 视图处理算法 TEMPTABLE
      • 题:
      • sql:
      • 解释
    • 2715 · 视图处理算法 Merge
      • 题:
      • sql:
      • 解释
    • 2709 · 删除视图(二)
      • 题:
      • sql:
    • 2708 · 删除视图(一)
      • 题:
      • sql:
    • 2707 · 视图的重命名(二)
      • 题:
      • sql:
    • 2706 · 视图的重命名(一)
      • 题:
      • sql:
    • 2705 · 显示当前数据库的视图
      • 题:
      • sql:
    • 2702 · 通过视图删除 Linghu Chong 的教师数据
      • 题:
      • sql:
    • 2700 · 通过视图更新 Linghu Chong 的年龄
      • 题:
      • sql:
    • 2692 · 统计每个教师教授的总学生数(视图)
      • 题:
      • sql:
    • 2689 · 重新定义 teachers 视图
      • 题:
      • sql:
    • 2665 · 认识视图(二)
      • 题:
      • sql:
    • 2654 · 给编号为 3 的数据上行锁(读锁)
      • 题:
      • sql:
      • 解释
    • 2633 · 排查当前数据库的行锁,查看行锁分析
      • 题:
      • sql:
    • 2627 · 排查当前数据库的表锁,查看表锁分析
      • 题:
      • sql:
    • 2620 · 查看 MySQL 数据库的自增锁模式
      • 题:
      • sql:
    • 2617 · 查看当前数据库的事务隔离级别
      • 题:
      • sql:
    • 2616 · 向教师表插入 Kansas 的信息
      • 题:
      • sql:
    • 2598 · 显示 teachers 表的所有触发器
      • 题:
      • sql:
    • 2587 · 删除 teachers 表信息时的关联处理(一)(触发器-删除之后触发)
      • 题:
      • sql:
      • 解释:触发器和存储过程的区别:
        • 触发器:
        • 存储过程:
    • 2568 · 删除触发器 "before_teachers_update"
      • 题:
      • sql:
    • 2567 · 删除触发器 "before_teachers_insert"
      • 题:
      • sql:
    • 2565 · 创建一个触发器 "before_teachers_update"(修改之前执行)
      • 题:
      • sql:
    • 2564 · 创建一个触发器 "before_teachers_insert"(新增之前执行)
      • 题:
      • sql:
    • 2092 · 查询授课教师编号(distinct 去重)
      • 题:
      • sql:
    • 2091 · 对课程表添加外键约束(添加物理联系)
      • 题:
      • sql:
      • 解释:
        • 什么是外键约束。
        • 有外键约束和没外键约束的区别:
          • 1、数据一致性和完整性
          • 2、数据删除与更新的控制
        • 总结:
    • 2086 · 查询 'U' 字开头且学生总数在 2000 到 5000 之间的教师国籍和该国籍教师的学生总数
      • 题:
      • sql:
    • 2082 · 统计每个老师教授课程的数量
      • 题:
      • sql:
    • 2062 · 查询指定老师教的所有课程的编号和名称(内连接 inner join)
      • 题:
      • sql:
    • 2060 · 查询 'Big Data' 课程对应的老师姓名
      • 题:
      • sql:
      • 解释
    • 2050 · 查询教师名称以及所教课程名称
      • 题:
      • sql:

炼码LintCode–数据库题库(级别:简单;数量:55道)–刷题笔记_02


炼码LintCode–数据库题库(级别:入门;数量:144道)–刷题笔记_01

炼码LintCode–数据库题库(级别:中等;数量:更新中~)–刷题笔记_03


在这里插入图片描述

3618 · 耗时前三的任务(日期差)

题:

在这里插入图片描述

sql:

select id , DATEDIFF(end_date , start_date) as 'diff' from Tasks
order by diff  desc limit 3;

解释:

DATEDIFF 天数差
-- 日期天数差
DATEDIFF(date1(新日期), date2(旧日期)):计算两个日期之间的天数差。

order by 别名
order by (别名diff) :在内部执行过程中,sql引擎已经计算出了列的值和别名,因此可以在 ORDER BY 子句中使用这些别名。

TIMESTAMPDIFF 月、年差

-- 如果是计算月份差的话,可以用这个函数
TIMESTAMPDIFF(MONTH, '2024-01-15', '2024-11-14')

-- 计算年份差
TIMESTAMPDIFF(YEAR, date1, date2)


3616 · 整合成绩单

题:

在这里插入图片描述

sql:

-- join(内连接) 只有那些在两个表中都有出现的学生(名字相同)才会出现在结果中

select c1.name , c1.score as 'score1' ,c2.score as 'score2' from course1_score c1 
join course2_score c2 on c1.name = c2.name
order by c1.name asc;

3614 · 查询客户的推荐人

题:

在这里插入图片描述

sql:


-- 注意点:null 也要算进去

select name from customer where referrer_id != 1 or referrer_id is null;

3613 · 查询成绩排名在第二到第五的学生

题:

在这里插入图片描述

sql:

select
 ROW_NUMBER() OVER (ORDER BY (course1 + course2 + course3) DESC, sno ASC) AS score_rank,
 sno , 
 (course1 + course2 + course3) as 'total_score' from score 
order by total_score desc , sno asc 
limit 1,4;

解释

ROW_NUMBER() 开窗函数排序

开窗函数 ROW_NUMBER() 详细解释

limit
limit 语法: LIMIT [offset], [count]
-- offset 是你希望跳过的行数。
-- count 是你希望返回的行数。

LIMIT 0, 1: 从第 0 行开始,返回 1 条数据。
LIMIT 1, 2: 从第 1 行开始,返回 2 条数据。

limit 1 :表示返回一条数据

如:a,b,c,d,e,f,g,h
limit 0: 返回0条数据
limit 1: 返回1条数据: a
limit 2: 返回2条数据: a,b
limit 0,1 跳过0行数据,返回1条数据:返回:a
limit 1,2 返回:b,c(这里1表示跳过第一条数据,返回2条数据)
limit 5,1 返回:f  (这里5表示跳过前面5条数据,返回接下来的1条数据)
limit 5,2 返回:f,g

limit 计算是从0开始的。比如a(0),b(1

3610 · 所有学生都选修的课程

题:

在这里插入图片描述

sql:

-- 因为要查所有学生都选修的课程,也就是所有学生的数量=该课程出现的次数

SELECT course_id
FROM courses
GROUP BY course_id
HAVING COUNT(DISTINCT student_id) = (SELECT COUNT(DISTINCT student_id) FROM courses)
order by course_id asc ;

解释

having、count、distinct
-- 因为要查所有学生都选修的课程,也就是所有学生的数量=该课程出现的次数
-- 因为学生会选多门课程,所以子查询的 student_id 要去重
HAVING COUNT(distinct student_id) = (SELECT COUNT(DISTINCT student_id) FROM courses)

3607 · 考试通过的人数

题:

在这里插入图片描述

sql:

select 

st.class , 
-- SUM() 函数会把每一行的布尔表达式结果(TRUE 或 FALSE)转换为 1 或 0,然后对所有行进行求和。因此,它可以准确地统计满足条件的行数。
sum(sc.course1 >= 60 and sc.course2 >= 60 and sc.course3 >= 60) as 'pass_count'

from  students st join score sc on st.sno = sc.sno
group by st.class 
having sum(sc.course1 >= 60 and sc.course2 >= 60 and sc.course3 >= 60);

解释

sum 数值和表达式区分
-- sum(某列) : 如果sum()里面具体是数值,那么就会进行求和。
-- sum(表达式 true或false):true 会等于1 ,false = 0,然后再求和。

-- SUM() 函数会把每一行的布尔表达式结果(TRUE 或 FALSE)转换为 1 或 0,然后对所有行进行求和。因此,它可以准确地统计满足条件的行数。

sum(sc.course1 >= 60 and sc.course2 >= 60 and sc.course3 >= 60) as 'pass_count'

3501 · 最棒的销售

题:

在这里插入图片描述

sql:


-- 写法1:
select id from sales 
where sales_sum = (select sales_sum from sales order by sales_sum desc limit 1);

-- 写法2:  

select id from  sales 
where sales_sum = (select max(sales_sum) from sales);

解释

直接使用子查询把最高的销售额查出来即可。
用 max 函数 或者 order by 获取第一个数据。


2812 · 存储过程变量(一)

题:

在这里插入图片描述

sql:


-- 设置存储过程的语句分隔符

-- DELIMITER $$ 

-- 创建一个名为:GetTotalTeacher 的存储过程
CREATE PROCEDURE GetTotalTeacher()

-- 存储过程开始:开始编写sql语句,实现逻辑代码
begin

-- 声明一个变量 totalTeacher, 默认值为 0
declare totalTeacher int default 0;

-- 获取teachers 表中的教师数量,用 into 关键字赋值给 totalTeacher 变量
select count(*) into totalTeacher from teachers;

-- 返回 totalTeacher 变量的值
select totalTeacher ;

-- 存储过程结束
end;

-- 将 $$ 分隔符恢复成默认的分号 ; 作为分隔符
-- DELIMITER ; 

解释

这里如果分隔符不注释掉的话,会报这个错,但是我看分隔符好像没啥问题。

在这里插入图片描述


2811 · 存储过程 INOUT 参数(二)

题:

在这里插入图片描述

sql:

CREATE PROCEDURE UpdateStudentCount(
    --inout 参数:表示输入输出参数,这个参数既可以在调用时传递一个初始值,也可以在存储过程内部被修改。存储过程内部的修改会影响传递给它的原始变量
    inout count int,
    -- in 参数:表示输入参数,这个参数的值在调用存储过程时传递给它,并且存储过程不能修改这个值。它是只读的。
    in des int
)
begin
    set count = count - des;
    -- 修改人数
    update courses set student_count = count  where name = 'Django';
end;

解释

-- 创建一个名为 UpdateStudentCount 的存储过程,然后有两个参数
CREATE PROCEDURE UpdateStudentCount(
    --inout 参数:表示输入输出参数,这个参数既可以在调用时传递一个初始值,也可以在存储过程内部被修改。存储过程内部的修改会影响传递给它的原始变量
    inout count int,
    -- in 参数:表示输入参数,这个参数的值在调用存储过程时传递给它,并且存储过程不能修改这个值。它是只读的。
    in des int
)

简单来说,inout 参数值可变 , in 参数值不可变。


2810 · 存储过程 INOUT 参数(一)

题:

在这里插入图片描述

sql:

create procedure UpdateTeacherAge(
    inout age int,
    in incr int
)
begin
    set age = age + incr;
    update teachers set age = age where name = 'Linghu Chong';
end;

2809 · 存储过程 OUT 参数(二)

题:

在这里插入图片描述

sql:


create procedure aaa(
    in Teacher int,
    out totalaaa int
)
begin
    select count(*) into totalaaa from courses where teacher_id = Teacher;
end;

-- 调用存储过程 ,@total 会保存存储过程输出的值(也就是 totalaaa ),
call aaa(3,@total);
-- 执行查询
select @total

解释

-- @total 和 totalaaa 的关系
-- 在存储过程内部,totalaaa 是输出参数,它保存了查询结果(即指定教师教授的课程数量)。在调用存储过程时,@total 用来接收存储过程输出的值。
-- totalaaa 和 @total 是相同的,只是它们处于不同的作用域:totalaaa 是存储过程内部的局部变量,而 @total 是存储过程外部的会话变量。


-- @ 符号用于标识 用户定义的变量(User-defined Variables),这些变量的作用范围通常是会话级的,即它们在当前数据库连接(会话)中有效,而非在存储过程内部


2808 · 存储过程 OUT 参数(一)

题:

在这里插入图片描述

sql:

create procedure bbb(
    -- 输入参数
    in teacherCountry varchar(10),
    -- 输出参数
    out total int
)
begin
    -- into 把值赋值给 total
    select count(*) into total from teachers where country = teacherCountry;
end;

-- 调用存储过程
call bbb('CN',@total);
-- 查询输出的值
select @total


2807 · 存储过程 IN 参数(二)

题:

在这里插入图片描述

sql:

create procedure ccc(
    -- 输入参数,只读
    in teacherAge int
)
begin

select * from teachers where age = teacherAge;

end;

-- 直接调用存储过程
call ccc(21);

2806 · 存储过程 IN 参数(一)

题:

在这里插入图片描述

sql:

create procedure ddd(
    in countryName varchar(25)
)
begin

select * from teachers where country = countryName;

end;

call ddd('CN');


2802 · 删除存储过程(二)

题:

在这里插入图片描述

sql:

drop procedure if exists getTeachers_2;

2801 · 删除存储过程(一)

题:

在这里插入图片描述

sql:

drop procedure if exists getTeachers;

2761 · 认识存储过程(二)

题:

在这里插入图片描述

sql:


-- 写法1:
SHOW CREATE PROCEDURE getTeachers;

-- 写法2:
SHOW PROCEDURE STATUS WHERE Name = 'getTeachers';

-- 写法3:
call getTeachers();


2760 · 认识存储过程(一)

题:

在这里插入图片描述

sql:

call getTeachers();

2725 · 视图的本地检查

视图本身是一种虚拟表,它只包含查询结果的数据,而不是存储数据。

题:

在这里插入图片描述

sql:

-- 基于v_teachers 表创建视图v_teachers_1,用 create view v_teachers_1 as  语法
create view v_teachers_1 as 
-- 要查询的数据
select * from  v_teachers where age < 20

2724 · 视图的级联检查

题:

在这里插入图片描述

sql:


-- 创建 v_teachers_1  视图,该视图数据来源于 v_teachers_1  视图。
create view v_teachers_1 as select * from v_teachers_1 where age  < 20;

2723 · 显示一个视图的定义

题:

在这里插入图片描述

sql:

-- SHOW CREATE VIEW 是用于显示视图的创建语句的命令,类似于 SHOW CREATE PROCEDURE 或 SHOW CREATE TABLE,它会返回视图创建时使用的 SQL 语句。

show create view v_teachers;

2721 · 创建一个确保一致性的视图(二)

题:

在这里插入图片描述

sql:


create view v_CN_teachers as select * from teachers where country = 'CN';


2720 · 创建一个确保一致性的视图(一)

题:

在这里插入图片描述

sql:

create view v_teachers as select * from teachers where age < 30;

2716 · 视图处理算法 TEMPTABLE

题:

在这里插入图片描述

sql:

-- algorithm 算法
-- algorithm=TEMPTABLE 强制 MySQL 使用 TEMPTABLE 算法

create  algorithm=TEMPTABLE view v_teachers as select * from teachers  where country = 'CN';

-- ALGORITHM=TEMPTABLE 强制 MySQL 使用 TEMPTABLE 算法。这意味着:

-- MySQL 在查询 v_teachers 视图时会先创建一个临时表来存储符合条件(country = 'CN')的教师记录。
-- 然后,外部查询将从这个临时表中获取数据,而不是直接查询原始的 teachers 表。

解释

TEMPTABLE:MySQL 会在执行视图时创建一个临时表。所有视图的查询结果会被存储在临时表中,外部查询再从该临时表中获取数据。

TEMPTABLE 算法适用于视图查询较复杂、无法直接合并的情况。虽然这样可能会稍微降低查询的效率,因为需要创建临时表,但它更具通用性,适用于大部分情况。


2715 · 视图处理算法 Merge

题:

在这里插入图片描述

sql:

create algorithm=Merge view v_teachers  as select * from teachers where age > 25;

解释

在这里插入图片描述


2709 · 删除视图(二)

题:

在这里插入图片描述

sql:

drop view v_courses_teachers;

2708 · 删除视图(一)

题:

在这里插入图片描述

sql:

drop view v_teachers;

2707 · 视图的重命名(二)

题:

在这里插入图片描述

sql:

rename table v_teachers_test to v_teachers;

2706 · 视图的重命名(一)

题:

在这里插入图片描述

sql:


rename table v_teachers to v_teachers_1;

2705 · 显示当前数据库的视图

题:

在这里插入图片描述

sql:

-- 用于列出当前数据库中所有类型为 VIEW 的对象(即视图)

-- show full tables 查询所有表
-- table_type = 'VIEW' 表的类型是 view (也就是视图)

show full tables where table_type = 'VIEW';

2702 · 通过视图删除 Linghu Chong 的教师数据

题:

在这里插入图片描述

sql:

delete from v_teachers where name = 'Linghu Chong';


2700 · 通过视图更新 Linghu Chong 的年龄

题:

在这里插入图片描述

sql:


update v_teachers set age = 30 where name = 'Linghu Chong';


2692 · 统计每个教师教授的总学生数(视图)

题:

在这里插入图片描述

sql:

create view v_teachers  as 
select vc.teacher_id, t.name,t.email ,t.age ,t.country,vc.student_count  
from v_courses vc left join teachers t on vc.teacher_id = t.id ;

2689 · 重新定义 teachers 视图

题:

在这里插入图片描述

sql:

-- ALTER VIEW 用于修改视图的定义,而不能直接用于修改视图返回的数据内容。
-- 视图本身是一种虚拟表,它只包含查询结果的数据,而不是存储数据。

alter view v_teachers as select * from teachers where country = 'CN';

2665 · 认识视图(二)

题:

在这里插入图片描述

sql:

show full tables;

2654 · 给编号为 3 的数据上行锁(读锁)

题:

在这里插入图片描述

sql:


select * from teachers where id = '3' LOCK IN SHARE MODE;

解释


LOCK IN SHARE MODE 作用:

查询该行数据的时候,加上这个读锁,作用是:
  当前事务在查询这条数据时,其实事务也能查这行数据,但是不能对这行数据进行修改。
  
  确保数据一致性和防止数据在读取过程中被其他事务修改


2633 · 排查当前数据库的行锁,查看行锁分析

题:

在这里插入图片描述

sql:

-- 查看行锁

SHOW STATUS LIKE 'Innodb_row_lock%';

2627 · 排查当前数据库的表锁,查看表锁分析

题:

在这里插入图片描述

sql:

-- 查看表锁

show status like 'Table%';

2620 · 查看 MySQL 数据库的自增锁模式

在 MySQL 中,自增锁(Auto-Increment Locking)是指当多个线程同时执行插入(INSERT)操作时,为了避免自增列(通常是主键)生成重复值,MySQL 会对自增列进行锁定。自增锁模式用于保证在并发插入时每个插入的自增值都是唯一且有序的。

题:

在这里插入图片描述

sql:


SHOW VARIABLES LIKE 'innodb_autoinc_lock_mode';


2617 · 查看当前数据库的事务隔离级别

题:

在这里插入图片描述

sql:


SHOW VARIABLES like '%isolation%';


2616 · 向教师表插入 Kansas 的信息

题:

在这里插入图片描述

sql:

-- 不要删除预置代码 --
-- 开启一个事务 -- 
BEGIN;

-- 插入 Kansas 的信息 --
-- Write your SQL Query here --

insert into teachers (name,email,age,country) values ('Kansas', null ,41,'UK');


COMMIT;

2598 · 显示 teachers 表的所有触发器

触发器(Trigger)是数据库管理系统(DBMS)中的一种特殊的存储过程,它会在数据库表中发生特定事件时自动执行。触发器与数据库表的操作(如插入、更新或删除)关联,当这些操作发生时,触发器会自动被触发并执行预定义的动作。触发器通常用于保证数据完整性、自动化任务以及审计操作等场景。

题:

在这里插入图片描述

sql:


-- triggers 触发器

show triggers;

2587 · 删除 teachers 表信息时的关联处理(一)(触发器-删除之后触发)

题:

在这里插入图片描述

sql:

-- 触发时机:我们使用 AFTER DELETE,即在教师数据被删除之后执行。
-- FOR EACH ROW:触发器针对每一行被删除的记录执行。如果有多条记录被删除,触发器会为每条记录执行一次。
-- OLD.teacher_id 引用了被删除教师记录的 teacher_id

-- 创建一个触发器 aaa ,在删除 teachers 表的每一行数据时被触发。
create trigger aaa after delete on teachers for each row

begin
    -- 在触发器中,OLD 关键字代表删除(或更新)前的记录。当触发器在 AFTER DELETE 事件上被触发时,OLD 表示已删除的记录的值。因此,OLD 访问的是被删除行的字段值。
    -- 这里的 old.id 是指被删除掉的teachers表的那行记录的id,不是指 courses 表的那行记录的id
    update courses set teacher_id = 0 where teacher_id = old.id;

end;

解释:触发器和存储过程的区别:

触发器:

创建触发器语法: create trigger aaa
MySQL 使用 FOR EACH ROW 来表明触发器是逐行处理的。

自动触发:触发器是自动执行的,当某个数据库事件(如 INSERT、UPDATE、DELETE)发生时,触发器会自动被调用。
无参数:触发器通常不接受外部输入参数,它会针对每一行受影响的数据自动执行。
绑定在事件上:触发器绑定在特定的表和事件(比如某表的插入、删除或更新)上。
应用场景:常用于数据完整性约束、审计、自动更新其他表等。

存储过程:

通常是通过 CREATE PROCEDURE 语句来定义,并且需要通过 CALL 来显式触发。

显式调用:存储过程需要显式调用(CALL 或 EXEC),你需要通过 SQL 命令或程序代码来触发它的执行。
可以有参数:存储过程可以接受输入和输出参数,可以根据传入的参数执行不同的操作。
独立于事件:存储过程通常是独立存在的,与特定的表或数据库事件没有直接绑定。
应用场景:常用于封装复杂的业务逻辑,批量操作,或需要与用户交互的任务。


2568 · 删除触发器 “before_teachers_update”

题:

在这里插入图片描述

sql:

drop trigger before_teachers_update;

2567 · 删除触发器 “before_teachers_insert”

题:

在这里插入图片描述

sql:


drop trigger before_teachers_insert;


2565 · 创建一个触发器 “before_teachers_update”(修改之前执行)

题:

在这里插入图片描述

sql:

-- 如果触发器只执行一个语句,set new.country = 'CN' 可以直接写在触发器体内:
create trigger before_teachers_update before update on teachers  for each row set new.country = 'CN';

-- 如果触发器中包含多个语句,比如你想修改多个字段或者执行其他逻辑,就需要使用 BEGIN 和 END;

2564 · 创建一个触发器 “before_teachers_insert”(新增之前执行)

题:

在这里插入图片描述

sql:

-- 触发器在数据修改之前执行,所以用 before 

create trigger before_teachers_insert before insert on teachers for each row set new.country = 'CN';


2092 · 查询授课教师编号(distinct 去重)

题:

在这里插入图片描述

sql:

select distinct teacher_id from courses;

2091 · 对课程表添加外键约束(添加物理联系)

题:

在这里插入图片描述

sql:


-- 在数据库中,主表是存储主键(通常是父表)的表,而从表则是包含外键(通常是子表)的表。
-- 主表(父表):teachers,其中的 id 是主键。
-- 从表(子表):courses,其中的 teacher_id 是外键,它引用了 teachers 表中的 id 列。

-- 给 courses 表中 teacher_id 添加外键约束的名称:fk_courses

-- 外键名称:fk_courses
-- 外键字段名称:teacher_id
-- 主表列名称:id

alter table courses add constraint fk_courses foreign key (teacher_id) references teachers(id) ;

-- alter: 修改
-- constraint :限制、约束
-- foreign : 外国的、外来的  ,foreign key 就是外键约束
-- references:参照


解释:

什么是外键约束。

外键约束:外键用来让两个表的数据之间建立连接,保证数据的一致性和完整性。

比如:以往teacher表的 id 和 student 表的 teacher_id 数据是一致的,如果没有给这个teacher_id 添加外键约束,
那么 这里的 id 和 student_id 只能说是有逻辑联系,但是没有物理联系。

只有逻辑联系的话,如果把teacher 表的某个老师的数据删掉,但是student表的某些学生数据依然有存在该老师的id,这就会造成数据不一致。
如果加上外键约束的话,那么在删除teacher表的某个老师的数据之前,和这个老师相关联的那些学生的 teacher_id,就得先处理好,才能删除老师的数据。


有外键约束和没外键约束的区别:

有外键约束和没有外键约束的区别,简而言之,主要体现在数据的一致性、完整性和约束控制方面。

1、数据一致性和完整性

有外键约束:数据库会确保子表中的外键列(如 courses.teacher_id)只包含父表(如 teachers.id)中存在的有效值。也就是说,子表中的外键值必须与父表的主键值匹配,防止插入无效的外键值。

没有外键约束:数据库不会强制检查外键列的值是否有效。因此,可能会插入无效或不一致的数据,比如 courses.teacher_id 的值指向 teachers 表中不存在的 id。

2、数据删除与更新的控制

有外键约束:可以通过定义级联删除(CASCADE)、级联更新(CASCADE)、置空(SET NULL)等规则来自动管理子表数据的删除或更新。例如,如果父表的某行数据被删除,子表中的相关数据也可以自动删除或更新,避免数据孤立。

没有外键约束:数据库不会自动管理删除或更新操作。如果父表的某条记录被删除或更新,子表中的相关记录将不会自动删除或更新,可能会留下“孤立记录”,即外键指向不存在的记录。

总结:

有外键约束:自动保证数据的一致性、完整性,防止不合法的数据插入和不一致的更新/删除操作。

没有外键约束:没有自动的数据一致性保障,容易导致无效或不一致的数据,需要开发人员手动管理。

有外键约束的数据库能确保数据的安全性和完整性,而没有外键约束则完全依赖于应用层的管理,容易出现错误和不一致的情况。


2086 · 查询 ‘U’ 字开头且学生总数在 2000 到 5000 之间的教师国籍和该国籍教师的学生总数

题:

在这里插入图片描述

sql:


select t.country , sum(student_count) as 'student_count' from courses c left join teachers t on c.teacher_id = t.id

-- 注意:这里的student_count是 sum(student_count) 的别名 'student_count',不是表里面的 student_count 字段。
-- 这里的student_count 的数据是经过 sum 合计出来的了,用的是上面的别名,这点不要搞混。
group by t.country having t.country like 'U%' and student_count between 2000 and 5000
-- 这个 student_count  也是,对应的是 sum(student_count) as 'student_count' 这里的 student_count。
order by student_count desc , t.country asc;


2082 · 统计每个老师教授课程的数量

题:

在这里插入图片描述

sql:

select t.name as 'teacher_name' , count(c.id) as 'course_count' from teachers t 
left join courses c on t.id = c.teacher_id 
group by t.id order by course_count desc , teacher_name asc;


2062 · 查询指定老师教的所有课程的编号和名称(内连接 inner join)

题:

在这里插入图片描述

sql:

-- 内连接:inner join ,只返回两个表中匹配的数据  , 和 join 是等价的。

select c.id , c.name as 'course_name', t.name as 'teacher_name' from courses c 
inner join teachers t on c.teacher_id = t.id
where t.name = 'Eastern Heretic'

2060 · 查询 ‘Big Data’ 课程对应的老师姓名

题:

在这里插入图片描述

sql:


select t.name from courses c inner join teachers t on c.teacher_id = t.id 
where c.name = 'Big Data';

解释

因为这道题的要求是【如果 teachers 表中没有 ‘Big Data’ 对应的老师,就什么都不返回】,所以不能用 left join 这种,因为查不到的话,返回的是null ,不是要求的不返回数据。

所以这里用的 inner join 内连接,如果没有匹配的数据则不返回。


2050 · 查询教师名称以及所教课程名称

题:

在这里插入图片描述

sql:

select c.name as 'course_name', t.name as 'teacher_name'  from teachers t
left join courses c on t.id = c.teacher_id;



本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2242935.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

洛谷刷题日记||基础篇8

#include <iostream> #include <vector> using namespace std;int N, M; // N为行数&#xff0c;M为列数 vector<vector<char>> field; // 表示田地的网格&#xff0c;每个元素是W或. vector<vector<bool>> visited; // 用来记录网格是否访…

在Ubuntu22.04上源码构建ROS noetic环境

Ubuntu22.04上源码构建ROS noetic 起因准备环境创建工作目录并下载源码安装编译依赖包安装ros_comm和rosconsole包的两个补丁并修改pluginlib包的CMakeLists的编译器版本编译安装ROS noetic和ros_test验证 起因 最近在研究VINS-Mono从ROS移植到ROS2&#xff0c;发现在编写feat…

从dos上传shell脚本文件到Linux、麒麟执行报错“/bin/bash^M:解释器错误:没有那个文件或目录”

[rootkylin tmp]#./online_update_wars-1.3.0.sh ba51:./online_update_wars-1.3.0.sh:/bin/bash^M:解释器错误:没有那个文件或目录 使用scp命令上传文件到麒麟系统&#xff0c;执行shell脚本时报错 “/bin/bash^M:解释器错误:没有那个文件或目录” 解决方法&#xff1a; 执行…

react+hook+vite项目使用eletron打包成桌面应用+可以热更新

使用Hooks-Admin的架构 Hooks-Admin: &#x1f680;&#x1f680;&#x1f680; Hooks Admin&#xff0c;基于 React18、React-Router V6、React-Hooks、Redux、TypeScript、Vite2、Ant-Design 开源的一套后台管理框架。https://gitee.com/HalseySpicy/Hooks-Adminexe桌面应用…

华东师范大学数学分析第五版PDF习题答案上册及下册

“数学分析”是数学专业最重要的一门基础课程&#xff0c;也是报考数学类专业硕士研究生的专业考试科目。为了帮助、指导广大读者学好这门课程&#xff0c;编者编写了与华东师范大学数学科学学院主编的《数学分析》(第五版)配套的辅导用书&#xff0c;以帮助读者加深对基本概念…

FineBI漏斗图分析转化率计算,需要获取当前节点和上一节点的转化率,需要获取错行值实现方案

FineBI漏斗图分析转化率计算&#xff0c;当前节点和上一节点的转化率&#xff0c;需要获取错行值 下面这张图大家很熟悉吧&#xff0c;非常经典的漏斗转化率分析。 从漏斗图看到需要计算转化率&#xff0c;都需要获取上一步漏斗的值&#xff0c;比如计算上一个省份的门店数量…

Solana 区块链的技术解析及未来展望 #dapp开发#公链搭建

随着区块链技术的不断发展和应用场景的扩展&#xff0c;性能和可拓展性成为各大公链竞争的关键因素。Solana&#xff08;SOL&#xff09;因其高吞吐量、低延迟和低成本的技术特性&#xff0c;在众多区块链项目中脱颖而出&#xff0c;被誉为“以太坊杀手”之一。本文将从技术层面…

FPGA开发-逻辑分析仪的应用-数字频率计的设计

目录 逻辑分析仪的应用 数字频率计的设计 -基于原理图方法 主控电路设计 分频器设计 顶层电路设计 数字系统开发不但需要进行仿真分析&#xff0c;更重要的是需要进行实际测试。 逻辑分析仪的应用 测试方式&#xff1a;&#xff08;1&#xff09;传统的测试方式&#…

基于python Django的boss直聘数据采集与分析预测系统,爬虫可以在线采集,实时动态显示爬取数据,预测基于技能匹配的预测模型

本系统是基于Python Django框架构建的“Boss直聘”数据采集与分析预测系统&#xff0c;旨在通过技能匹配的方式对招聘信息进行分析与预测&#xff0c;帮助求职者根据自身技能找到最合适的职位&#xff0c;同时为招聘方提供更精准的候选人推荐。系统的核心预测模型基于职位需求技…

kubesphere环境-本地Harbor仓库+k8s集群(单master 多master)+Prometheus监控平台部署

前言&#xff1a;半月前在公司生产环境上离线部署了k8s集群Victoria Metrics(二开版)自研版夜莺 监控平台的搭建&#xff0c;下面我租用3台华为云服务器演示部署kubesphere环境-本地Harbor仓库k8s集群&#xff08;单master节点 & 单master节点&#xff09;Prometheus监控部…

车载诊断框架 --- UDS小白入门篇

我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 所有人的看法和评价都是暂时的&#xff0c;只有自己的经历是伴随一生的&#xff0c;几乎所有的担忧和畏惧…

强大的正则表达式——Easy

进入题目界面输入难度1后&#xff0c;让我们输入正则表达式&#xff08;regex&#xff09;&#xff1a; 目前不清楚题目要求&#xff0c;先去下载附件查看情况&#xff1a; import re import random# pip install libscrc import libscrcallowed_chars "0123456789()|*&q…

字节青训-小C的外卖超时判断、小C的排列询问

目录 一、小C的外卖超时判断 问题描述 测试样例 解题思路&#xff1a; 问题理解 数据结构选择 算法步骤 最终代码&#xff1a; 运行结果&#xff1a; 二、小C的排列询问 问题描述 测试样例 最终代码&#xff1a; 运行结果&#xff1a; ​编辑 一、小C的外卖超时判断…

游戏引擎学习第13天

视频参考:https://www.bilibili.com/video/BV1QQUaYMEEz/ 改代码的地方尽量一张图说清楚吧,懒得浪费时间 game.h #pragma once #include <cmath> #include <cstdint> #include <malloc.h>#define internal static // 用于定义内翻译单元内部函数 #…

C++11(五)----lambda表达式

文章目录 lambda表达式 lambda表达式 lambda表达式可以看作一个匿名函数 语法 [capture-list] (parameters) mutable -> return-type { statement } auto func1 [](int a, int b) mutable -> int {return a b; }; *capture-list&#xff1a;捕捉列表。编译器根据[]来 判…

CSS基础知识05(弹性盒子、布局详解,动画,3D转换,calc)

目录 0、弹性盒子、布局 0.1.弹性盒子的基本概念 0.2.弹性盒子的主轴和交叉轴 0.3.弹性盒子的属性 flex-direction row row-reverse column column-reverse flex-wrap nowrap wrap wrap-reverse flex-dirction和flex-wrap的组合简写模式 justify-content flex-s…

【Qt聊天室】客户端实现总结

目录 1. 项目概述 2. 功能实现 2.1 主窗口设计 2.2 功能性窗口 2.3 主界面功能实现 2.4 聊天界面功能实现 2.5 个人信息功能开发 2.6 用户信息界面设置功能 2.7 单聊与群聊 2.8 登录窗口 2.9 消息功能 3. 核心设计逻辑 3.1 核心类 3.2 前后端交互与DataCenter 4…

RK3568平台开发系列讲解(高级字符设备篇)IO 模型引入实验

🚀返回专栏总目录 文章目录 一、IO 的概念二、IO 执行过程三、IO 模型的分类阻塞 IO非阻塞 IOIO 多路复用信号驱动异步 IO沉淀、分享、成长,让自己和他人都能有所收获!😄 一、IO 的概念 IO 是英文 Input 和 Output 的首字母, 代表了输入和输出, 当然这样的描述有一点点…

简单实现QT对象的[json]序列化与反序列化

简单实现QT对象的[json]序列化与反序列化 简介应用场景qt元对象系统思路实现使用方式题外话 简介 众所周知json作为一种轻量级的数据交换格式&#xff0c;在开发中被广泛应用。因此如何方便的将对象数据转为json格式和从json格式中加载数据到对象中就变得尤为重要。 在python类…

【qt】控件2

1.frameGeometry和Geometry区别 frameGeometry是开始从红圈开始算&#xff0c;Geometry从黑圈算 程序证明&#xff1a;使用一个按键&#xff0c;当按键按下,qdebug打印各自左上角的坐标&#xff08;相当于屏幕左上角&#xff09;&#xff0c;以及窗口大小 Widget::Widget(QWid…