Multi-table operations (1-to-1, 1-to-many, many-to-many)

※Multi-table operation (for all multi-tables, association technology must be used (merge multiple tables into a new table): left association, right association, inner association. There is also an outer (full) association, which MySQL does not support, for consideration The software is compatible, we generally do not use it for development.)

※The relationship between tables: 1-to-1, 1-to-many, many-to-many-
one, 1-to -
1 The primary key id of the main table, plus unique)

CREATE TABLE man(
  id VARCHAR(32) PRIMARY KEY,
  NAME VARCHAR(30)
);

CREATE TABLE woman(
  id VARCHAR(32) PRIMARY KEY,
  NAME VARCHAR(30),
  husband VARCHAR(32) UNIQUE,
  CONSTRAINT wm_fk FOREIGN KEY(husband) REFERENCES man(id)
);

Note: Husband needs to add unique constraint here, if not, it is a one-to-many relationship

Adding unique is a 1-to-1 relationship

 

//DROP TABLE woman;

INSERT INTO man VALUES('1','Xiao Ming');
INSERT INTO man VALUES('2','Xiao Cong');
INSERT INTO man VALUES('3','Pharaoh');

INSERT INTO woman VALUES('1','Xiaohua','2');
INSERT INTO woman VALUES('2','Xiaojing','1');
INSERT INTO woman VALUES('3','Xiaohong' ,'1');//Error: Violation of 1 to 1
INSERT INTO woman VALUES('3','Xiaohong','10');//Error: Violation of foreign key -- the foreign key value must exist in the main table

INSERT INTO man VALUES('10','Wang Liu');
INSERT INTO woman VALUES('3','Xiaoyu','10');//OK

 

Constrained by unique, husband cannot be repeated otherwise

husband is a foreign key and is also constrained by the id in man

 

 

//◇ Query husband and wife information (inline)
SELECT man.name AS husband, woman.name AS wife FROM man
      INNER JOIN woman ON man.id=woman.husband;

SELECT m.name AS 丈夫, w.name AS 妻子 FROM man AS m
      INNER JOIN woman AS w ON m.id=w.husband;

 

 

2. 1-to-many
※The third normal form: 1 party builds the main table (id is the primary key field), multi-party builds the foreign key field (pid--refer to the primary key id of the main table, do not add unique)
CREATE TABLE person2(
  id VARCHAR(32) PRIMARY KEY,
  NAME VARCHAR(30),
  sex CHAR(1)
);

DROP TABLE car2;
CREATE TABLE car(
  id VARCHAR(32) PRIMARY KEY,
  NAME VARCHAR(30),
  price NUMERIC(10,2),
  pid VARCHAR(32),
  CONSTRAINT car_fk FOREIGN KEY(pid) REFERENCES person2(id)
);

INSERT INTO person2 VALUES('P01','Jack','1');
INSERT INTO person2 VALUES('P02','Tom','1');
INSERT INTO person2 VALUES('P03','Rose','0');

INSERT INTO car VALUES('C001','BMW',30,'P01');
INSERT INTO car VALUES('C002','BEnZ',40,'P01');
INSERT INTO car VALUES('C003','Audi',40,'P01');

INSERT INTO car VALUES('C004','QQ',5.5,'P02');
//外键字段值可以为“NULL”表示该车还未卖出
INSERT INTO car(id,NAME,price) VALUES('C005','ABC',10);
INSERT INTO car(id,NAME,price) VALUES('C006','BCD',10);

 

//◇查询哪些人有哪些车
SELECT *  FROM car INNER JOIN person2 ON car.pid=person2.id;
SELECT person.NAME,car.name FROM person
               INNER JOIN car ON person.id=car.pid;


//◇查询Jack有哪些车
SELECT car.NAME,car.price,person2.name  FROM car
         INNER JOIN person2 ON car.pid=person2.id where person2.name='Jack';


//◇查询哪些人有两辆或两辆以上的车
//失败品:--每组只显示第一条
SELECT car.NAME,car.price,person2.name  FROM car
  INNER JOIN person2 ON car.pid=person2.id GROUP BY person2.id HAVING COUNT(car.pid)>=2;   

//过渡版 
 SELECT car.NAME,car.price,person2.name  FROM car
  INNER JOIN person2 ON car.pid=person2.id WHERE person2.id IN('P01','P02');
SELECT pid FROM car GROUP BY pid HAVING COUNT(pid)>=2; //把上面写死的pid写成活的

//OK版 
 SELECT car.NAME,car.price,person2.name  FROM car
  INNER JOIN person2 ON car.pid=person2.id WHERE person2.id IN(
     SELECT pid FROM car GROUP BY pid HAVING COUNT(pid)>=2
  );

 

//演示左关联: SELECT * FROM person2 LEFT JOIN car ON car.pid=person2.id;//由全表可知只需条件是car.id或NAME或price或pid为空即可查出谁没有车


//◇查询哪些人没有车
SELECT person2.name FROM person2 LEFT JOIN car ON car.pid=person2.id
    WHERE car.id IS NULL;

其实右关联跟左关联一样,只需要把左关联的表调换一下位置便成了右关联的结果,所以只要会了左关联,右关联也是一样的。

 

//◇补一个外键的概念(默认是约束): 删除主键信息时,当该主键字段值在外键表中存在时,该记录是不能删除的。---要把外键表是的相关信息删除之后,才能删除。 ---更新同理
DELETE FROM person2 WHERE id='P01';//car表中存在pid='P01'的车,所以主表不能删除'P01'这条记录

 

 

 

三、多对多( 3个表= 2个实体表 + 1个关系表 )

※第三范式: 两个实体都建成独立的主表, 另外再单独建一个关系表(采用联合主键)
1、分别建议两个实体表(没有外键,但有自己的主键, 没有冗余信息)
//DROP TABLE stud;
//学生表
CREATE TABLE stud(
  id VARCHAR(32) PRIMARY KEY,
  NAME VARCHAR(30)
);
//课程表
CREATE TABLE ject(
  id VARCHAR(32) PRIMARY KEY,
  NAME VARCHAR(30)
);

 

2、另外补建一个关系表
CREATE TABLE sj(
  studid VARCHAR(32) NOT NULL,
  jectid VARCHAR(32)
);
//注意,要先建联合主键,再添加外键。顺序不能反了。
ALTER TABLE sj ADD CONSTRAINT sj_pk PRIMARY KEY(studid,jectid);
ALTER TABLE sj ADD CONSTRAINT sj_fk1 FOREIGN KEY(studid) REFERENCES stud(id);
ALTER TABLE sj ADD CONSTRAINT sj_fk2 FOREIGN KEY(jectid) REFERENCES ject(id);

//删除外键约束
//ALTER TABLE sj DROP FOREIGN KEY sj_fk1;
//ALTER TABLE sj DROP FOREIGN KEY sj_fk2;


3、添加一些演示数据
//实体表1
INSERT INTO stud VALUES('S001','Jack');
INSERT INTO stud VALUES('S002','Rose');
INSERT INTO stud VALUES('S003','Tom');

//实体表2
INSERT INTO ject VALUES('J001','Java');
INSERT INTO ject VALUES('J002','Oracle');
INSERT INTO ject VALUES('J003','XML');
INSERT INTO ject VALUES('J004','JSP');
INSERT INTO ject VALUES('J005','Game');

//关系表
INSERT INTO sj VALUES('S001','J001');
INSERT INTO sj VALUES('S001','J003');
INSERT INTO sj VALUES('S001','J004');
INSERT INTO sj VALUES('S002','J002');
INSERT INTO sj VALUES('S002','J003');
INSERT INTO sj VALUES('S002','J004');


//查询哪些人选了哪些课
//SQL组织的1992标准,可用,但效率不高
SELECT stud.name, ject.NAME FROM stud,ject,sj WHERE stud.id=sj.studid AND ject.id=sj.jectid;

//SQL组织的1996标准,效率高,推荐使用---关联
SELECT stud.name, ject.NAME FROM stud INNER JOIN sj ON stud.id=sj.studid
                                      INNER JOIN ject ON ject.id=sj.jectid;

 

//查询哪些人没选课
SELECT stud.name FROM stud LEFT JOIN sj ON stud.id=sj.studid
       LEFT JOIN ject ON ject.id=sj.jectid where ject.id is NULL;

 

//查询哪些课没人选
SELECT ject.name FROM stud RIGHT JOIN sj ON stud.id=sj.studid
       RIGHT JOIN ject ON ject.id=sj.jectid where stud.id is NULL;

 

 

 

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324385025&siteId=291194637