Mysql学习

一、数据准备

# 创建数据库
create database sql50;
use sql50;

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for Teacher
-- ----------------------------
DROP TABLE IF EXISTS `Teacher`;
CREATE TABLE `Teacher`  (
  `TId` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `Tname` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of Teacher
-- ----------------------------
INSERT INTO `Teacher` VALUES ('01', '张三');
INSERT INTO `Teacher` VALUES ('02', '李四');
INSERT INTO `Teacher` VALUES ('03', '王五');

SET FOREIGN_KEY_CHECKS = 1;


SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for Course
-- ----------------------------
DROP TABLE IF EXISTS `Course`;
CREATE TABLE `Course`  (
  `CId` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `Cname` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `TId` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of Course
-- ----------------------------
INSERT INTO `Course` VALUES ('01', '语文', '02');
INSERT INTO `Course` VALUES ('02', '数学', '01');
INSERT INTO `Course` VALUES ('03', '英语', '03');

SET FOREIGN_KEY_CHECKS = 1;

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for Student
-- ----------------------------
DROP TABLE IF EXISTS `Student`;
CREATE TABLE `Student`  (
  `SId` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `Sname` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `Sage` datetime(0) NULL DEFAULT NULL,
  `Ssex` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of Student
-- ----------------------------
INSERT INTO `Student` VALUES ('01', '赵雷', '1990-01-01 00:00:00', '男');
INSERT INTO `Student` VALUES ('02', '钱电', '1990-12-21 00:00:00', '男');
INSERT INTO `Student` VALUES ('03', '孙风', '1990-12-20 00:00:00', '男');
INSERT INTO `Student` VALUES ('04', '李云', '1990-12-06 00:00:00', '男');
INSERT INTO `Student` VALUES ('05', '周梅', '1991-12-01 00:00:00', '女');
INSERT INTO `Student` VALUES ('06', '吴兰', '1992-01-01 00:00:00', '女');
INSERT INTO `Student` VALUES ('07', '郑竹', '1989-01-01 00:00:00', '女');
INSERT INTO `Student` VALUES ('09', '张三', '2017-12-20 00:00:00', '女');
INSERT INTO `Student` VALUES ('10', '李四', '2017-12-25 00:00:00', '女');
INSERT INTO `Student` VALUES ('11', '李四', '2012-06-06 00:00:00', '女');
INSERT INTO `Student` VALUES ('12', '赵六', '2013-06-13 00:00:00', '女');
INSERT INTO `Student` VALUES ('13', '孙七', '2014-06-01 00:00:00', '女');

SET FOREIGN_KEY_CHECKS = 1;


SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for SC
-- ----------------------------
DROP TABLE IF EXISTS `SC`;
CREATE TABLE `SC`  (
  `SId` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `CId` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `score` decimal(18, 1) NULL DEFAULT NULL
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of SC
-- ----------------------------
INSERT INTO `SC` VALUES ('01', '01', 80.0);
INSERT INTO `SC` VALUES ('01', '02', 90.0);
INSERT INTO `SC` VALUES ('01', '03', 99.0);
INSERT INTO `SC` VALUES ('02', '01', 70.0);
INSERT INTO `SC` VALUES ('02', '02', 60.0);
INSERT INTO `SC` VALUES ('02', '03', 80.0);
INSERT INTO `SC` VALUES ('03', '01', 80.0);
INSERT INTO `SC` VALUES ('03', '02', 80.0);
INSERT INTO `SC` VALUES ('03', '03', 80.0);
INSERT INTO `SC` VALUES ('04', '01', 50.0);
INSERT INTO `SC` VALUES ('04', '02', 30.0);
INSERT INTO `SC` VALUES ('04', '03', 20.0);
INSERT INTO `SC` VALUES ('05', '01', 76.0);
INSERT INTO `SC` VALUES ('05', '02', 87.0);
INSERT INTO `SC` VALUES ('06', '01', 31.0);
INSERT INTO `SC` VALUES ('06', '03', 34.0);
INSERT INTO `SC` VALUES ('07', '02', 89.0);
INSERT INTO `SC` VALUES ('07', '03', 98.0);

SET FOREIGN_KEY_CHECKS = 1;

二、SQL各种连接查询详解

2.1、交叉连接

-- 交叉连接(不带on子句,返回的是两表的乘积,也叫笛卡尔积)
# 隐式交叉连接 没有cross join
SELECT * from Student , Course WHERE CId = '03';
# 显式交叉连接 有cross join
SELECT * from Student CROSS JOIN Course WHERE CId = '03';

2.2、内连接

# 隐式的内连接,没有inner join,形成的中间表为两个表的笛卡尔积。
SELECT * FROM Student, SC WHERE Student.SId = SC.SId;

# 显示的内连接,一般称为内连接,有inner join,形成的中间表为两个表经过on条件过滤后的笛卡尔积。
SELECT * FROM Student INNER JOIN SC on Student.SId = SC.SId;

2.3、外连接

# 1、左外连接(left outer join) 左表全部数据+右表符合要求数据
SELECT Student.Sname , SC.score from Student LEFT JOIN SC on Student.SId = SC.SId;

# 2、右外连接(left outer join) 左表符合要求数据+右表全部数据
SELECT Student.Sname , SC.score from Student RIGHT JOIN SC on Student.SId = SC.SId;

# 3、全外连接(不重复全集)
# mysql是不支持全外的连接的,这里给出的写法适合oracle和db2。
SELECT Student.Sname , SC.score from Student RIGHT JOIN SC on Student.SId = SC.SId;

# 推荐在写连接查询的时候,on后面只跟连接条件,而对中间表限制的条件都写到where子句中。
SELECT Student.Sname , SC.score from Student LEFT JOIN SC on Student.SId = SC.SId WHERE SC.score>88.0;

两表连接查询选择方式的依据:

1、 查两表关联列相等的数据用内连接。

2、 col_l是col_r的子集时用右外连接。

3、 col_r是col_l的子集时用左外连接。

4、 col_r和col_l彼此有交集但彼此互不为子集时候用全外。

5、 求差操作的时候用联合查询。

三、备

四、sql 50 题

4.1. 查询"01"课程比"02"课程成绩高的学生的信息及课程分数

# 左连接自交
select *
from Student as s
         right join
     (
         select t1.SId, score_for_c01, score_for_c02
         from (select SId, score as score_for_c01 from SC as sc where sc.CId = 01) as t1,
              (select SId, score as score_for_c02 from SC as sc where sc.CId = 02) as t2
         where t1.SId = t2.SId
           and t1.score_for_c01 > t2.score_for_c02
     ) as r
     on s.SId = r.SId;

# +---+-----+-------------------+----+---+-------------+-------------+
# |SId|Sname|Sage               |Ssex|SId|score_for_c01|score_for_c02|
# +---+-----+-------------------+----+---+-------------+-------------+
# |02 |钱电   |1990-12-21 00:00:00|男   |02 |70.0         |60.0         |
# |04 |李云   |1990-12-06 00:00:00|男   |04 |50.0         |30.0         |
# +---+-----+-------------------+----+---+-------------+-------------+

4.2.查询同时存在"01"课程和"02"课程的情况

# 注意查找效率,每次生成的关系表越小越好
select t1.*, t2.CId, t2.score
from (select * from SC as sc where sc.CId = '01') as t1,
     (select * from SC as sc where sc.CId = '02') as t2
where t1.SId = t2.SId;

# +---+---+-----+---+-----+
# |SId|CId|score|CId|score|
# +---+---+-----+---+-----+
# |01 |01 |80.0 |02 |90.0 |
# |02 |01 |70.0 |02 |60.0 |
# |03 |01 |80.0 |02 |80.0 |
# |04 |01 |50.0 |02 |30.0 |
# |05 |01 |76.0 |02 |87.0 |
# +---+---+-----+---+-----+

4.3.查询存在"01"课程但可能不存在"02"课程的情况(不存在时显示为null)

# 典型的外联结
select t1.*, t2.CId, t2.score
from (select * from SC as sc where sc.CId = '01') as t1
         left join
     (select * from SC as sc where sc.CId = '02') as t2
     on t1.SId = t2.SId;

# +---+---+-----+----+-----+
# |SId|CId|score|CId |score|
# +---+---+-----+----+-----+
# |01 |01 |80.0 |02  |90.0 |
# |02 |01 |70.0 |02  |60.0 |
# |03 |01 |80.0 |02  |80.0 |
# |04 |01 |50.0 |02  |30.0 |
# |05 |01 |76.0 |02  |87.0 |
# |06 |01 |31.0 |NULL|NULL |
# +---+---+-----+----+-----+

4.4. 查询不存在"01"课程但存在"02"课程的情况

# 采用子查询(联结也可以,但本题子查询简单)
select *
from SC as sc
where sc.SId not in (
    select SId
    from SC as sc
    where sc.CId = '01'
)
  AND sc.CId = '02';

# +---+---+-----+
# |SId|CId|score|
# +---+---+-----+
# |07 |02 |89.0 |
# +---+---+-----+

4.5.查询平均成绩大于等于60分的同学的学生编号和学生姓名和平均成绩

# 聚合函数分组和HAVING条件过滤,获得sid,最后与学生表联结
select s.SId, s.Sname, t.avg_score
from Student as s
         inner join (select SId, avg(score) as avg_score
                     from SC
                     group by SId
                     having avg_score >= 60) as t
                    on s.SId = t.SId;

# +---+-----+---------+
# |SId|Sname|avg_score|
# +---+-----+---------+
# |01 |赵雷   |89.66667 |
# |02 |钱电   |70.00000 |
# |03 |孙风   |80.00000 |
# |05 |周梅   |81.50000 |
# |07 |郑竹   |93.50000 |
# +---+-----+---------+
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值