1. 程式人生 > >多對多關係的多表關聯查詢

多對多關係的多表關聯查詢

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(),只是作用於數值型別資料,用於返回指定資料的和,空值會被預設忽略。