html格式的网站地图,王烨鑫,佛山快速建站哪家服务专业,小浪底水利枢纽建设管理局网站1 多表
学生表、班级表、课程表、班级课程表 关系型数据库#xff1a; MySql、SqlServer、Oracle 相同的数据出现多次绝不是一件好事#xff0c;这是关系数据库设计的基础。关系表的设计就是要把信息分解成多个表#xff0c;一个数据一个表#xff0c;各表通过某些共同的…1 多表
学生表、班级表、课程表、班级课程表 关系型数据库 MySql、SqlServer、Oracle 相同的数据出现多次绝不是一件好事这是关系数据库设计的基础。关系表的设计就是要把信息分解成多个表一个数据一个表各表通过某些共同的值互相连接所以才叫关系数据库。 将数据存储到多个表能更有效的存储更方便的处理但这些好处是有代价的如果数据存储在多个表中怎么用一条SELECT语句就检索出数据呢答案是使用子查询、联结
非关系型数据库 Redis MongoDB 速度非常快日志信息 可以理解为一个大的Map结构
-- 多对多
-- 班级表
CREATE TABLE banji(id INT PRIMARY KEY AUTO_INCREMENT,name CHAR(10) NOT NULL
);INSERT INTO banji(name) VALUES (Java1807), (Java1812);-- 学生表
CREATE TABLE student(id INT PRIMARY KEY AUTO_INCREMENT,name CHAR(10) NOT NULL,age INT,gender CHAR(1),banji_id INT,FOREIGN KEY(banji_id) REFERENCES banji(id)
);INSERT INTO student(name,age,gender,banji_id)
VALUES(张三,23,男,1),(李四,21,男,2),(王五,20,女,1);-- INSERT INTO student(name,age,gender,banji_id) VALUES(张三,23,男,3);-- 课程表
CREATE TABLE course(id INT PRIMARY KEY AUTO_INCREMENT,name CHAR(10) NOT NULL,credit INT COMMENT 学分
);
INSERT INTO course(name,credit) VALUES(Java,5),(UI,4),(H5,4);-- 班级课程表
CREATE TABLE banji_course(-- id INT PRIMARY KEY AUTO_INCREMENT,banji_id INT,course_id INT,PRIMARY KEY (banji_id,course_id),-- 联合主键FOREIGN KEY(banji_id) REFERENCES banji(id),FOREIGN KEY(course_id) REFERENCES course(id)
); INSERT INTO banji_course(banji_id, course_id) VALUES(1,1),(1,3),(2,1),(2,2),(2,3);-- 子查询嵌套查询一个查询语句是另一个查询语句的条件
-- 查询班级是Java1812班所有学生信息
-- SELECT * FROM student WHERE banji_id 2;
SELECT id FROM banji WHERE nameJava1812;
SELECT * FROM student WHERE banji_id (SELECT id FROM banji WHERE nameJava1807);-- 班级是java1807班或者java1812班所有学生信息SELECT * FROM student WHERE banji_id1 OR banji_id2;
SELECT * FROM student WHERE banji_id IN(1,2);
SELECT id FROM banji WHERE nameJava1807 OR nameJava1812;
-- ① 不行
SELECT * FROM student WHERE banji_id (SELECT id FROM banji WHERE nameJava1807 OR nameJava1812);
-- ② 可以 太长
SELECT * FROM student WHERE banji_id (SELECT id FROM banji WHERE nameJava1807) OR
banji_id (SELECT id FROM banji WHERE nameJava1812);
-- ③ OK
SELECT * FROM student WHERE banji_id IN (SELECT id FROM banji WHERE nameJava1807 OR nameJava1812);-- 计算字段使用子查询班级id 班级名字 班级人数
-- 执行这条查询遵循下面的步骤
-- 1、从banji表检索班级列表
-- 2、对检索出的每个banji统计其在student表中的数量
-- 班级id 班级名字 班级人数
-- 数据库 ExcelSELECT id,name,(SELECT COUNT(*)FROM student WHERE student.banji_id banji.id) AS total_count
FROM banji;SELECT id,name,(SELECT COUNT(*)FROM studentWHERE student.banji_idbanji.id) AS total_count
FROM banji
ORDER BY name DESC;total_count是一个计算字段它是由括号中的子查询建立的该子查询对检索出的每个banji执行一次 总结 1、“”要求子查询只有一个结果。 “in”子查询可以有多个结果。 2、子查询的SELECT语句只能查询单个列企图检索多个列将返回错误。 3、能嵌套的子查询的数目没有限制不过在实际使用时由于性能的限制不能嵌套太多的子查询。 子查询也可以使用下面的连接来实现
2 等值连接
从左表中取出每一条记录去右表中与所有的记录进行匹配匹配必须是某个条件在左表中与右表中相同最终才会保留结果否则不保留
笛卡尔积 由没有联结条件的表关系返回的结果为笛卡尔积。检索出的行的数目将时第一个表中的行数乘以第二个表中的行数。通俗的说就是查询所得的结果行数是两张表行数的乘积。 返回笛卡尔积的联结也称为叉联结cross join。
-- 笛卡尔积 等值连接
SELECT *
FROM student,banjiSELECT *
FROM student,banji
WHERE student.banji_idbanji.id;注意联结查询非常消耗资源因此应该注意不要联结不必要的表。联结的表越多性能下降越厉害。
3 内连接
内连接有两种写法一种是inner join另一种是join这两种写法都是一样的可以理解为join是inner join的缩写。还可以看出等值连接和内连接的效果一样但是开发中建议使用内连接
-- 内连接SELECT *
FROM student INNER JOIN banji;-- 与笛卡尔积效果一样SELECT *
FROM student AS s INNER JOIN banji AS b-- 与等值连接效果一样
ON s.banji_idb.id;-- 查询的结果也是一张表 分组 按班级分组 数数量 刚才的统计班级人数SELECT id, -- 子查询name,(SELECT COUNT(*)FROM student WHERE student.banji_idbanji.id) AS total_count
FROM banji;SELECT b.id,b.name,COUNT(*) AS total_count -- 内连接结果 作为新表在新表里用GROUP
FROM student AS s INNER JOIN banji AS b
ON s.banji_idb.id
GROUP BY b.id;-- 分组SELECT b.id,b.name
FROM student AS s INNER JOIN banji AS b
ON s.banji_idb.id
GROUP BY b.id;-- 分组-- 学生id 学生姓名 班级名称
SELECT s.id AS 学生ID,s.name AS 学生姓名,b.name AS 班级名称
FROM student AS s INNER JOIN banji AS b-- 与内连接效果一样
ON s.banji_idb.id;-- 学生id 学生姓名 班级名称 课程名称 学分
SELECT *
FROM student AS s INNER JOIN banji AS b-- 与内连接效果一样
ON s.banji_idb.id
INNER JOIN banji_course AS bc
ON b.idbc.banji_id;-- 内连接
SELECT s.id AS 学生ID,s.name AS 学生姓名,b.name AS 班级名称,c.name AS 课程名称,c.credit AS 学分
FROM student AS s INNER JOIN banji AS b-- 与内连接效果一样
ON s.banji_idb.id
INNER JOIN banji_course AS bc
ON b.idbc.banji_id
INNER JOIN course AS c
ON bc.course_idc.id
ORDER BY s.id;
-- 把inner join之后查询的结果当成一张表来使用 在这个结果集里面根据班级id统计每个班级下面学生数量。
-- 等值连接没有WHERE 就是笛卡尔积
SELECT s.id AS 学生ID,s.name AS 学生姓名,b.name AS 班级名称,c.name AS 课程名称,c.credit AS 学分
FROM student s,banji b,banji_course bc,course c
WHERE s.banji_idb.id AND b.idbc.banji_id AND bc.course_idc.id
ORDER BY s.id;总结多表查询主要是注意下面两点 1、整个查询涉及到几张表涉及到几张表就连接这几张表。 2、如果涉及到这几张表的关系搞不清楚画一下ER图弄清楚表和表之间的关系就是根据外键建立的关系
4 inner join on、left join on、right join on区别
inner join on 只有左右两个表有关联的才查询出来 left join on 左表中都显示出来右表没有显示空 right join on 右表都显示左表没有显示空 左连接也成为左外连接从左表那里返回所有的行即使在右表中没有匹配的行.left join on
-- inner join on、left join on、right join on区别SELECT *
FROM student AS s INNER JOIN banji AS b
ON s.banji_idb.id;SELECT *
FROM student AS s LEFT JOIN banji AS b
ON s.banji_idb.id;SELECT *
FROM student AS s RIGHT JOIN banji AS b
ON s.banji_idb.id;5 模糊查找
语法形式字段 like 要查找字符 说明 1、like模糊查找用于对字符类型的字段进行字符匹配查找。 2、要查找的字符中有两个特殊含义的字符% , _: 2.1: %含义是代表0或多个的任意字符 2.2: _含义是代表1个任意字符 3、语法like %关键字%
SELECT * FROM student WHERE name LIKE 张%; -- 以张开头
SELECT * FROM student WHERE name LIKE 张_; -- 以张开头而且名字是两个字
SELECT * FROM student WHERE name LIKE %张%; -- 名字里面只要有张就可以注意: NULL 通配符%看起来像是可以匹配任何东西但有个例外这就是NULL
SELECT * FROM student WHERE name LIKE %;不会匹配name为NULL的行
-- 模糊查找
SELECT * FROM student WHERE name 张三;
SELECT * FROM student WHERE name LIKE %张%;
SELECT * FROM student WHERE name LIKE 张%;
SELECT * FROM student WHERE name LIKE 张_;
SELECT * FROM student WHERE name LIKE %张;
SELECT * FROM student WHERE name LIKE %;-- 把id是1的学生名字改为张三age:24,gender:女UPDATE student SET age 24,name张三三 WHERE id1;注意(也是面试题) SQL的通配符很有用但这种功能是有代价的即通配符搜索要消耗更长的处理时间使用通配符的技巧 1、不要过度使用通配符。如果其他操作符能达到相同的目的应该使用其他操作符。 2、在确实需要使用通配符时也尽量不要把它们用在搜索模式的开始处 %张。把通配符置于开始处搜索起来是最慢的。