美文网首页
关系型数据库数据表之间关系、select语句

关系型数据库数据表之间关系、select语句

作者: 222AblackA | 来源:发表于2018-12-25 23:02 被阅读0次

    一.关系型数据库数据表之间的关系:一对多,多对一,多对多

    a.数据完整性:

    关系型数据库可以保证数据的完整性:
      -- 实体完整性: 每条记录都是独一无二的,没有冗余 -- 主键、唯一索引
      -- 参照完整性(引用完整性):外键
      -- 域完整性: 数据类型,非空约束,默认值约束,检查约束(Oracl支持,MySQL不支持)
    

    b.数据表关系:

        create table tb_college
        (
        colid int auto_increment,
        colname varchar(20) not null,
        website varchar(255),
        primary key (colid)
        );
    
        -- 修改tb_college表 添加主键约束
        -- alter table tb_college add constraint pk_college_id primary key (colid);
    
        -- 修改tb_college表,给website字段添加唯一性约束
        alter table tb_college add constraint uni_college_website unique (website);
    
        -- 删除名为uni_college_website的唯一性约束
        alter table tb_college drop index uni_college_website;
    
        insert into tb_college (colname,website) values 
        ('计算机学院','http://www123.com'),
        ('管理学院','http://www.baidu.com'),
        ('汽车学院','http://www.jindong.com');
        
        select * from tb_college;
        -- 修改学生表tb_student,给学生加一个列,表示在哪一个学院
        alter table tb_student add column colid int comment '所在学院编号';
    
        -- 修改学生表tb_student添加外键约束(外来主键:外键),限制学生表中的学院 标号必须参照学院表的学院编号
        alter table tb_student add constraint  fk_student_colid foreign key (collid) references tb_college (colid);
        
    
        -- 总结:如果要维持两个实体(表)之间一对多或多对一的关系
        -- 需要在多的一方添加一个外键列简历起参照完整性即可
        
    
        create table tb_course
        (
        courid int auto_increment comment '课程名称',
        courname varchar(50) not null comment '课程名字',
        credit tinyint not null comment '学分 ',
        primary key (courid)
        );
        
    
        create table tb_teather
        (
        teathid int auto_increment comment '老师编号',
        teathname varchar(20) not null comment '老师姓名',
        teathtitle varchar(20) not null comment '职称',
        colid int not null comment '所属学院',
        primary key (teathid)
        );
    
        -- 修改老师表,添加外键约束
        alter table tb_teather add constraint fk_teather_colid foreign key (colid) references tb_college (colid);
    
        -- 修改课程表,添加外键列
        alter table tb_course add column teathid int comment '添加外键列';
    
        -- 修改课程表,添加外键约束
        alter table tb_course add constraint fk_course_teathid foreign key (teathid)
        references tb_teather (teathid);
        
    
        -- 关系型数据库里面,多对多关系需要通过创建中间表来维持
        create table tb_score
        (
        scid int auto_increment comment '选课编号',
        sid int not null comment '学号',
        cid int not null comment '课程编号',
        -- 分数:四位有效数字,小数点后面1位
        mark decimal(4,1) not null comment '考试成绩',
        primary key (scid),
        foreign key (sid) references tb_student (stuid),
        foreign key (cid) references tb_course (courid)
        );
    
    
        -- 将学生学号和课程编号作为一个组合,添加唯一性约束
        alter table tb_score add constraint uni_score_sid_cid
        unique (sid,cid);
    

    二.select 查询语句

    insert into tb_score (sid, cid, seldate, mark) values 
    (1001, 1111, '2017-09-01', 95),
    (1001, 2222, '2017-09-01', 87.5),
    (1001, 3333, '2017-09-01', 100),
    (1001, 4444, '2018-09-03', null),
    (1001, 6666, '2017-09-02', 100),
    (1002, 1111, '2017-09-03', 65),
    (1002, 5555, '2017-09-01', 42),
    (1033, 1111, '2017-09-03', 92.5),
    (1033, 4444, '2017-09-01', 78),
    (1033, 5555, '2017-09-01', 82.5),
    (1572, 1111, '2017-09-02', 78),
    (1378, 1111, '2017-09-05', 82),
    (1378, 7777, '2017-09-02', 65.5),
    (2035, 7777, '2018-09-03', 88),
    -- now()是mysql的一个获取当前时间(格林尼治标准时间)的函数,date(now())获取当前时间的日期段,time(now())获取当前时间的时间段
    (2035, 9999, date(now()), null),
    (3755, 1111, date(now()), null),
    (3755, 8888, date(now()), null),
    (3755, 9999, '2017-09-01', 92);
    
    
    
      -- 查询所有学生信息
        select * from tb_student;
        -- 查询所有课程名称及学分(投影:指定看那些列/别名:as给投影的数据重新取名字)
        select cname as 课程名称,credit as 学分 from tb_course;
        -- 查询所有女学生的姓名和出生日期(筛选)
        select sname,birth from tb_student where gender=0;
        -- 查询所有80后学生的姓名、性别和出生日期(筛选)
        select
           sname as 姓名,
             case gender when 1 then '男' else '女' end as 性别,
             birth as 出身日期 
        from tb_student 
        where birth between '1980-1-1' and '1989-12-31';
        
        -- 使用函数写性别男和女的显示(只有MySQL可以用,其他数据库不能用)
        select
           sname as 姓名,
             if(gender,'男','女') as 性别,
             birth as 出身日期 
        from tb_student 
        where birth between '1980-1-1' and '1989-12-31';
        -- 查询四个字符的名字的学生:length()函数,获取字符的字节数
        select stuid as 学号,sname as 名字 from tb_student where length(sname)/3=4;
        -- 查询姓”杨“的学生姓名和性别(模糊)
        select sname as 姓名,if (gender,'男','女') as 性别
        from tb_student where sname like '杨%';
        -- 查询姓”杨“名字两个字的学生姓名和性别(模糊)
        select sname as 姓名,if(gender,'男','女') as 性别
        from tb_student where sname like '杨_';
        -- 查询姓”杨“名字三个字的学生姓名和性别(模糊)
        select sname  as 姓名,if(gender,'男','女') as 性别 
        from tb_student where sname like '杨__';
        -- 查询名字中有”不“字或“嫣”字的学生的姓名(模糊)
        select sname as 姓名 from tb_student where sname like '%不%' or sname like '%嫣%';
         -- 查询没有录入家庭住址的学生姓名(空值)
        --  
        select sname as 姓名 from tb_student where addr is null or addr='';
        -- 查询录入了家庭住址的学生姓名(空值)
        select sname as 姓名 from tb_student where addr is not null and addr<>'';
        -- 查询学生选课的所有日期(去重)
        select distinct seldate from tb_score;
        -- 查询学生的家庭住址(去重)
        select distinct addr as 家庭住址 from tb_student  where addr is not null and addr<>'';
        -- 查询男学生的姓名和生日按年龄从大到小排列(排序):desc(降序),asc(升序),升序可以不写asc,默认是升序(执行时先where再order by)
        select sname as 姓名,year(now())-year(birth) as 年龄 from tb_student where gender=1 order by 年龄 asc;
        -- 女生全排前面 ,男生全排后面,并且学号从大到小可以加多个排序关键字
        select stuid,sname,gender from tb_student order by gender asc,stuid desc;
        -- 5个聚合函数(在所有数据库中都能用):min/max/sum/avg/count
        --     空值不纳入计算
        -- 查询年龄最大的学生的出生日期(聚合函数)
        select min(birth) from tb_student;
        -- 查询年龄最小的学生的出生日期(聚合函数)
        select max(birth) from tb_student;
        -- 查询男女学生的人数(分组和聚合函数)
        select if(gender,'男','女') as 性别,count(stuid) as 人数 from tb_student group by gender;
        -- 查询课程编号为1111的课程的平均成绩(筛选和聚合函数)
        select avg(mark) from tb_score where cid=1111;
        -- 查询学号为1001的学生所有课程的平均分(筛选和聚合函数)
        select avg(mark) from tb_score where sid=1001;
        -- 查询每个学生的学号和平均成绩(分组和聚合函数)
        select sid as 学号,avg(mark) as 平均成绩 from tb_score group by sid;
        -- 查询平均成绩大于等于90分并且学号在1000到4000之间学生的学号和平均成绩
        -- 分组之前的筛选用where,分组之后的筛选用having
        select sid as 学号,avg(mark) as 平均成绩 from tb_score where sid between 1000 and 3999 group by sid having 平均成绩>=90 order by 平均成绩 desc;
        -- 查询年龄最大的学生的姓名(子查询/嵌套查询)
        -- select里面再嵌套一个select
        select sname as 姓名 from tb_student where birth=(select min(birth) from tb_student);
        -- 查询年龄最大的学生姓名和年龄(子查询+运算)
        select sname as 姓名,birth as 出身日期 from tb_student where birth=(select min(birth) from tb_student);
        -- 查询选了两门以上的课程的学生姓名(子查询/分组条件/集合运算)
        select sid from tb_score group by sid having count(sid)>=2;
        
        select sname as 姓名 from tb_student where stuid in(select sid from tb_score group by sid having count(sid)>2);
        -- 查询学生姓名、课程名称以及成绩(连接查询)
        select sname,cname,mark from tb_student,tb_course,tb_score where stuid=sid and couid=cid;
        -- 查询选课学生的姓名和平均成绩(子查询和连接查询)
            -- 方法一
            select sname as 姓名,avgmark as 平均分 from tb_student t1,
            (select sid,avg(mark) as avgmark from tb_score group by sid) t2
            where stuid=sid;
        
        
            -- 方法二
            select sname as 姓名,avgmark as 平均分 from tb_student t1 inner join
            (select sid,avg(mark) as avgmark from tb_score group by sid) t2
            on stuid=sid;
        
        -- 查询每个学生的姓名和选课数量(左外连接和子查询):outer可以省略
        -- 在连接多表查询时写在前面的表称为左表,写在后面的表叫右表
        -- MySQL不支持全外连接:full outer join
        -- 左外连接(left outer join):将左表不满足连表条件的记录也要查出来,不满足连表条件的地方补上空值null;
        -- 右外连接(right outer join):将右表不满足连表条件的记录也要查出来,不满足连表条件的地方补上空值null;
        
        
        select sname as 姓名,ifnull(total,0) as 选课数量 from tb_student t1 left outer join 
        (select sid,count(sid) as total from tb_score group by sid) t2
        on stuid=sid;

    相关文章

      网友评论

          本文标题:关系型数据库数据表之间关系、select语句

          本文链接:https://www.haomeiwen.com/subject/tutclqtx.html