多对多关系的多表关联查询

1.什么是多对多关系

       多对多关系(百度):多对多关系是关系数据库中两个表之间的一种关系, 该关系中第一个表中的一个行可以与第二个表中的一个或多个行相关。第二个表中的一个行也可以与第一个表中的一个或多个行相关。

       下面我就举个比较好理解的例子来说明这个概念。学生和学生所选的选修课之间的关系,就符合多对多的关系,怎么理解呢?一个学生可能会选择多门选修课,而,一门选修课则可能会对应多个学生,下面我以此为例子来说明这个问题。


2.前期准备

创建物理表,并且初始化测试数据(笔者创建在mysql)

创建学生表(STUDENT)

CREATE TABLE STUDENT(  
   ID   VARCHAR(20) primary key,  
   NAME VARCHAR(20),  
   AGE INT  
); 

创建选修课程表(SUBJECT)

CREATE TABLE SUBJECT(  
   ID   VARCHAR(20) primary key,  
   NAME VARCHAR(40)  
);

创建学生和选修课程的关联表(STU_REF_SUB)

CREATE TABLE STU_REF_SUB(  
   STUDENT_ID VARCHAR(20),  
   SUBJECT_ID VARCHAR(20)  
);

添加外键

ALTER TABLE STU_REF_SUB ADD CONSTRAINT FK_STUDENT FOREIGN KEY(STUDENT_ID) REFERENCES STUDENT(ID);
ALTER TABLE STU_REF_SUB ADD CONSTRAINT FK_SUBJECT FOREIGN KEY(SUBJECT_ID) REFERENCES SUBJECT(ID);

添加联合主键

ALTER TABLE STU_REF_SUB ADD CONSTRAINT PK_STU_REF_SUB PRIMARY KEY(STUDENT_ID,SUBJECT_ID); 

诸表数据初始化

STUDENT表数据初始化

INSERT INTO STUDENT VALUES('STU001','李白',25);  
INSERT INTO STUDENT VALUES('STU002','杜甫',26);  
INSERT INTO STUDENT VALUES('STU003','欧阳修',27);  
INSERT INTO STUDENT VALUES('STU004','岳飞',26);  
INSERT INTO STUDENT VALUES('STU005','柳永',28); 

SUBJECT表数据初始化

INSERT INTO SUBJECT VALUES('SUB001','网球课');  
INSERT INTO SUBJECT VALUES('SUB002','诗词课');  
INSERT INTO SUBJECT VALUES('SUB003','计算机');  
INSERT INTO SUBJECT VALUES('SUB004','乒乓球');  
INSERT INTO SUBJECT VALUES('SUB005','篮球课');

STU_REF_SUB表数据初始化

INSERT INTO STU_REF_SUB VALUES('STU001','SUB001');  
INSERT INTO STU_REF_SUB VALUES('STU001','SUB003');  
INSERT INTO STU_REF_SUB VALUES('STU001','SUB004');  
INSERT INTO STU_REF_SUB VALUES('STU002','SUB002');  
INSERT INTO STU_REF_SUB VALUES('STU002','SUB004');  
INSERT INTO STU_REF_SUB VALUES('STU004','SUB001');  
INSERT INTO STU_REF_SUB VALUES('STU004','SUB005');  
INSERT INTO STU_REF_SUB VALUES('STU005','SUB003'); 

3.场景查询

查询哪些学生选了课程

sql语句(方式一)

select 
    student.name '学生名称',  
    subject.name '课程名称'   
from  
    student,  
    subject,  
    stu_ref_sub    
where   
    student.id = stu_ref_sub.student_id   
and subject.id = stu_ref_sub.subject_id;

(方式一)查询结果如下


竖表转化为横表

select 
    t1.student '学生姓名',
    max(case t1.course when '网球课' then '网球课' else '0' end) '课程一',
    max(case t1.course when '计算机' then '计算机' else '0' end) '课程二',
    max(case t1.course when '篮球课' then '篮球课' else '0' end) '课程三',
    max(case t1.course when '乒乓球' then '乒乓球' else '0' end) '课程四',
    max(case t1.course when '诗词课' then '诗词课' else '0' end) '课程五'
from
  (
   select 
       student.name as student,  
       subject.name as course   
   from  
       student,  
       subject,  
       stu_ref_sub    
   where   
       student.id = stu_ref_sub.student_id   
   and subject.id = stu_ref_sub.subject_id
  ) t1
group by t1.student

竖转横查询结果如下


(方式一)查询小结

       1.在将竖表转化为横表的时候,笔者在这里使用了聚合函数max(),需要注意的是,聚合函数max()不仅可以作用于数值类型的数据,还可以作用于字符串类型数据和日期时间类型的数据。而sum(),只是作用于数值类型数据,用于返回指定数据的和,空值会被默认忽略。

  • 35
    点赞
  • 131
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
MyBatis-Plus是一个基于MyBatis的增强工具,它提供了很多便捷的功能来简化开发。在MyBatis-Plus中,多表关联查询多对一可以通过使用@ManyToOne注解来实现。 首先,需要在实体类中定义多对一的关系。假设我们有两个实体类:Order和User,一个订单对应一个用户。在Order实体类中,我们可以使用@ManyToOne注解来定义多对一的关系: ```java public class Order { // 其他属性... @ManyToOne @JoinColumn(name = "user_id") private User user; // 其他方法... } ``` 在User实体类中,我们可以使用@OneToMany注解来定义一对多的关系: ```java public class User { // 其他属性... @OneToMany(mappedBy = "user") private List<Order> orders; // 其他方法... } ``` 接下来,在查询订单时,可以使用MyBatis-Plus提供的Wrapper来进行多表关联查询。例如,我们想要查询订单及其对应的用户信息,可以使用如下代码: ```java QueryWrapper<Order> wrapper = new QueryWrapper<>(); wrapper.select("order_id", "order_name", "user_id", "user_name") .leftJoin("user", "order.user_id = user.user_id") .eq("order_id", orderId); Order order = orderMapper.selectOne(wrapper); ``` 上述代码中,我们使用leftJoin方法进行左连接查询,将订单和用户进行关联。通过select方法指定需要查询的字段,然后通过eq方法指定查询条件。最后,使用selectOne方法执行查询操作。 这样,就可以实现多表关联查询多对一的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值