python爬虫学习笔记-SQL学习

2023-11-15

Sql概述

  • 先来看一个例子:小王第一次使用数据库,然后跟数据库来了个隔空对话

    在这里插入图片描述

    • 其实,我们想一想,mysql是一个软件,它有它自己一套的管理规则,我们想要跟它打交道,就必须遵守它的规则,如果我想获取数据,它自己有一套规则,这个规则就是SQL。
  • 什么是sql?

    • SQL : 结构化查询语言(Structured Query Language)简称SQL,是一种特殊目的的编程言,是一种数据库查询和程序设计语言,SQL语言主要用于存取数据、查询数据、更新数据和管理关系数据库系统,SQL语言由IBM开发。
    • 其实简单的说,就是你发送给他能识别的暗号,他懂了就会给你返回数据。
    • 注意:
      • 对于关系型数据库而言,SQL语句是通用的,学会了一种,其他只是一些细微的差别,毕竟人家数据库也是一个种族,语言是通用的,只不过有些存在方言的差别。
  • sql的分类

    • SQL语言分为3种类型:

      1、DDL语句 数据库定义语言: 数据库、表、视图、索引、存储过程,例如CREATE DROP ALTER

      2、DML语句 数据库操纵语言: 插入数据INSERT、删除数据DELETE、更新数据UPDATE、查询数据SELECT

      3、DCL语句 数据库控制语言: 例如控制用户的访问权限GRANT、REVOKE

库表操作DDL

库的增删改查

这里的库指的数据库,也就是我们所谓的那个文件夹,一般情况下,我们在开发项目前,会先设计数据库中相关表结构,一个项目中所有表都会放在同一个文件夹下,对于库的操作属于SQL分类中的DDL,也就是数据库定义语言。

  • 创建数据库

  •  create database 仓库名;
    
  • 创建数据库并制定编码:utf8设置好后,就表示数据库中可以存储中文数据

  • create database 仓库名 charset utf8;
    
  • 使用数据库

  • use 仓库名;
    
  • 查看所有数据库和单独常看当前数据库

  • show databases;  #查看当前所有的数据仓库
    select database(); #查看当前使用的是哪一个数据仓库
    #注意:sql语句不区分大小写,但是sql中使用的标识符尽量控制大小写
    
  • 修改数据库

    • 数据库的名称一旦创建好之后就无法修改
    • 修改数据库一般只修改编码
  • alter database 仓库名 charset gbk #将数据的字符集编码修改成了gbk
    
  • 删除数据库

  • drop database 仓库名;
    
表的增删改查
创建表
  • create table 表名(
      字段名1 类型(宽度) 约束条件,
      字段名2 类型(宽度) 约束条件,
      字段名3 类型(宽度) 约束条件,
    );
    注意:
    	1.字段名不能重复
    	2.宽度和约束条件可选
    	3.字段名和类型是必须的
    
查看表结构
  • desc 表名;
    
数据类型

**字符串:**顾名思义,就是存储的一连串的字符,例如文字

在这里插入图片描述

数值型:常用的有:int ,double, float
在这里插入图片描述

  • 整数型:int 基本int能够处理日常工作中大部分整数存储问题

  • 小数型:double float

    • 强调一下float(5,2)其中5代表总长度,2代表小数长度,这个意思是整数是3位,小数是2位
  • 日常工作中float足以解决小数问题了。

日期类型

  • now()函数:返回当前系统时间

  • date:年月日

  • time:时分秒

  • datetime:年月日时分秒

create table t(date1 date,date2 time,date3,datetime);
insert into t(now(),now(),now());
mysql> select * from t;
+------------+----------+---------------------+
| date1      | date2    | date3               |
+------------+----------+---------------------+
| 2020-04-15 | 16:02:43 | 2020-04-15 16:02:43 |
+------------+----------+---------------------+
1 row in set (0.00 sec)

ENUM和SET类型

  • 这里的类似于下拉字段,在进行数据插入的时候,必须选择事先设置的内容
  • 对于set而言,可以多选,但是enum只能单选

在这里插入图片描述

create table UserData (
	id int, #用户编号
	money float(9,2),#用户余额
	registTime datetime,#用户的注册时间
	usernmae varchar(50),
	sex enum('male','female'),#单选
	address set('BJ','SH','GZ')#多选
)
约束条件
  • 为了防止不符合规范的数据进入数据库,在用户对数据进行插入、修改、删除等操作时,DBMS自动按照一定的约束条件对数据进行监测,使不符合规范的数据不能进入数据库,以确保数据库中存储的数据正确、有效、相容。

  • 约束条件与数据类型的宽度一样,都是可选参数,主要分为以下几种:

    • NOT NULL :非空约束,指定某列不能为空;
    • DEFAULT:默认值
    • UNIQUE : 唯一约束,指定某列或者几列组合不能重复
    • PRIMARY KEY :主键,指定该列的值可以唯一地标识该列记录
    • FOREIGN KEY :外键,指定该行记录从属于主表中的一条记录,主要用于参照完整性
  • not null:不为空,当你设置一个字段时,不允许它为空,可以使用此约束条件

  • create table t1 (
    	id int,
    	name varchar(20) not null#name字段的值不可以为空
    )
    
  • default 默认值

    • 例如:对于性别一列,如果大部分都是男性,可以设置成默认值,不填则取默认值,填写了则覆盖默认值
  • create table t2 (
    	id int,
    	name varchar(20),
    	sex char(10) DEFAULT('male')
    	
    )
    
  • unique 唯一:当有一列字段你不想让它有重复值时,可以设置为唯一

create table t3 (
	id int unique, #唯一约束
	name varchar(20)
)
  • 联合唯一:只有当你设置的这些字段同时重复时才会报错
create table t4 (
	id int, 
	name varchar(20),
	dep char(10),
	UNIQUE(name,dep) #联合唯一约束
)
  • primary key

    • 主键为了保证表中的每一条数据的该字段都是表格中的唯一值。换言之,它是用来独一无二地确认一个表格中的每一行数据。

    • 主键可以包含一个字段或多个字段。当主键包含多个字段时,称为组合键 (Composite Key),也可以叫联合主键。

    • 单字段主键:

    • create table t5 (
      	id int PRIMARY KEY , #主键约束 
      	name varchar(20),
      	salary float(6,2)
      )
      
    • 联合主键:

    • create table t6 (
      	id int, #主键约束 
      	name varchar(20),
      	salary float(6,2),
      	PRIMARY KEY(id,name) #联合主键
      )
      
  • auto_increment 自增字段:

    • 对于主键id而言,往往我们可以设置为自增字段,不用手动填写

    • create table t7 (
      	id int PRIMARY KEY auto_increment, #主键约束 
      	name varchar(20)
      )
      
  • foreign key

    • 思考:

      • 假设我们要描述所有公司的员工,需要描述的属性有这些 : 姓名,年龄,性别,部门,部门描述

      • 公司有3个部门,但是有1个亿的员工,那意味着部门和部门描述这两个字段需要重复存储,部门名字和部门描述内容越长,越浪费内存,如何处理呢?

        • 解决方法: 我们完全可以定义一个部门表然后让员工信息表关联该表,如何关联,即foreign key

        在这里插入图片描述

        • foreign key(当前表中建立关系的外键字段) references 被关联表名(id)

        • #创建两张表:
          #被关联表:dep:
          create table dep(
              id int primary key auto_increment,
              dep_name varchar(16),
              dep_desc varchar(255));
          
          #关联表:emp:	
          create table emp(
              id int primary key auto_increment,
              name varchar(6),
              age int,
              gender enum('male','female'),
              dep_id int not null,
              foreign key(dep_id) references dep(id));
          
    • 级联删除,级联更新

      • 两张表建立关联之后,如果部门表某个部门的砍掉了,那对应的人员表中的那些部门的人员相应的该怎么处理呢?可以保存,也可以随之一起删除.

        • 如果要保证两表一致,则需要在设置外键时添加on delete cascade

        • 如果部门id更新了,要一起更新的话,则添加on update cascade

        • #被关联表:dep:
          create table dep(
              id int primary key auto_increment,
              dep_name varchar(16),
              dep_desc varchar(255));
          
          #关联表:emp:	
          create table emp(
              id int primary key auto_increment,
              name varchar(6),
              age int,
              gender enum('male','female'),
              dep_id int not null,
              foreign key(dep_id) references dep(id) on delete cascade on update cascade
          )
          
修改表
  • 修改表名

  • alter table 旧表名 rename 新表名
    
  • 修改表字段的数据类型

  • alter table 表名 modify 字段 新数据类型
    
  • 修改表字段名

  • alter table 表名 change 旧字段名 新字段名 新数据类型 
    
  • 新增字段

  • alter table 表名 add 新增字段名 数据类型 约束条件#约束条件可选
    
  • 删除字段

  • alter table 表名 drop 字段名
    
  • 查看所有的表

  • show tables
    
删除表
drop table 表名

记录操作DML

插入数据
  • 插入完整的数据

  • insert into 表名 (字段1,字段2) values ('字段1的值','字段2的值')
    
    create table new_dep(
    	id int PRIMARY KEY auto_increment,
    	dep_name varchar(10),
    	dep_desc varchar(100)
    );
    
    • #给指定字段插入数据
      insert into new_dep (dep_name,dep_desc) 
      values ('yanfabu','ssss');
      insert into new_dep (dep_name,dep_desc) 
      values ('销售部','ssss');
      
      
  • 插入多条数据

  • insert into 表名 values ('xx1','xx2'),(xx1,xx2) #插入几条数据就写几个括号
    
更新数据
  • 单独更新一个字段

  • update 表名 set 字段名 = 字段值 where 条件
    
  • 更新多个字段

  • update 表名 set 字段1 = 字段值1,字段2 = 字段值2 where 条件
    
删除数据
  • 删除指定数据数据

  • delete from 表名 where 条件
    
  • 删除表中所有数据

  • #不加where条件就是清空表,一定要慎重使用delete
    # 如果有自增id,新增的数据,仍然是以删除前的最后一样作为起始。
    delete from 表名
    
    # 数据量大,删除速度比上一条快,且直接从零开始
    truncate table t1;
    
查询数据
单表查询
  • 准备数据

  • #创建员工表,字段为:
    #id自增,员工名不能为空,性别只可以为male或者female且不能为空,默认值为male
    #age不能为空,默认值28,入职日期只显示年月日,职位名称,工资保留两位小数,办公室门牌号,部门id
    create table emp (
    	id int PRIMARY KEY auto_increment,
    	name char(20) not null,
    	gender enum('male','female') default 'male',
    	age int not null default 28,
    	hire_date date,
    	job_title varchar(30),
    	salary float(10,2),
    	office_num int,
    	dep_id int
    )
    	
    数据
    insert into emp (name,gender,age,hire_date,job_title,salary,office_num,dep_id)values
    ('weiwei','male',78,'20150302','teacher',1000000.31,401,1),
    ('lala','male',81,'20130305','teacher',8300,401,1),
    ('zhangsan','male',73,'20140701','teacher',3500,401,1),
    ('liulaogen','male',28,'20121101','teacher',2100,401,1),
    ('aal','female',18,'20110211','teacher',9000,401,1),
    ('zhugelang','male',18,'19000301','teacher',30000,401,1),
    ('成龙','male',48,'20101111','teacher',10000,401,1),
    ('歪歪','female',48,'20150311','sale',3000.13,402,2),#以下是销售部门
    ('丫丫','female',38,'20101101','sale',2000.35,402,2),
    ('丁丁','female',18,'20110312','sale',1000.37,402,2),
    ('星星','female',18,'20160513','sale',3000.29,402,2),
    ('格格','female',28,'20170127','sale',4000.33,402,2),
    ('张野','male',28,'20160311','operation',10000.13,403,3), #以下是运营部门
    ('程咬金','male',18,'19970312','operation',20000,403,3),
    ('程咬银','female',18,'20130311','operation',19000,403,3),
    ('程咬铜','male',18,'20150411','operation',18000,403,3),
    ('程咬铁','female',18,'20140512','operation',17000,403,3)
    
  • 查询所有字段信息

  • select * from 表名; #星华表示的是通配符,表示所有的字段
    
  • 查询指定字段信息

  • select 字段1,字段2 from 表名
    select name,salary from emp #查看所有员工的姓名和薪资的信息
    
  • 通过四则运算查询

  • #查看员工的姓名和其年薪
    select name,salary*12 from emp
    #as可以给列起一个别名,as关键字可以省略
    select name,salary*12 as year_salary from emp
    
  • 为库表重命名

  • select * from emp as e #e就是emp的别名
    
  • 条件查询where语句

    • 单条件查询

    • #查询销售员工的姓名和薪资
      select name,salary from emp where job_title = 'sale'
      
    • 多条件查询1:结合and

    • #查询薪资大于1w的老师对应的名字和薪资
      select name,salary from emp where job_title = 'teacher' and salary > 10000 
      
      
    • 多条件查询2:结合or

    • #查询薪资为3,3.5,4,9k的员工名字和具体薪资
      select name,salary from emp where salary = 3000 or salary = 3500 or salary = 4000 or salary = 9000
      
    • 多条件查询3:结合between…and

    • #查询薪资范围在1000-5000之间的员工名字和具体信息
      select name,salary from emp where salary between 1000 and 5000
      
      
    • 多条件查询4:结合in

    • #查询薪资为3,3.5,4,9k的员工名字和具体薪资
      select name,salary from emp where salary in (3000,3500,4000,9000)
      
    • 多条件查询5:结合not in

    • select name,salary from emp where salary not in (3000,3500,4000,9000)
      
      
    • 模糊查询like

      • 通配符%:表示多个字符

        • select * from emp where name like 'a%'
          
      • 通配符_:表示一个字符

        • select * from emp where name like 'zhang___'
          
  • 分组查询:group by

    • 简单的分组查询

      • 注意:使用group by的查询字段必须是分组字段(或者是其他字段的聚合形式),否则会出错,想要获取其他字段信息,可以借助于聚合函数
    • select job_title from emp group by job_title
      
    • 分组聚合

    • #查看每一个岗位的人数
      #count()使用来做计数操作
      select job_title, count(id)from emp group by job_title
      
      #计算男女员工的平均年龄
      select gender,avg(age) from emp group by gender
      
      #计算不同岗位员工的平均薪资
      select job_title,avg(salary) from emp group by job_title
      
      #查看男女员工的最大,最小年级和整体年龄
      select gender,max(age),min(age),sum(age) from emp group by gender
      
    • having子句

      • where 与 having的区别:

        • where 是针对分组之前的字段内容进行过滤,而having是针对分组后的
      • 注意:having后面的条件字段只可以是分组后结果中存在的字段名,否则会报错!

      • #查看销售岗位的平均薪资
        select job_title,avg(salary) from emp GROUP BY job_title having job_title = 'sale'
        
  • 排序:order by

    • 升序: order by 字段 asc(默认升序,可以不写)

    • 降序: order by 字段 desc

    • 单列排序:

    • select * from emp order by salary
      
    • 多列排序:越前面的列优先级越高

    • select * from emp order by salary desc
      
  • limit

    • 显示前三条数据

    • select * from emp limit 3
      
    • 从0开始,先查出第一条,然后包含这条再往后查5条

    • select * from emp limit 0,5
      
    • 从第3开始,即先查出第4条,然后包含这条再往后查7条

    • select * from emp limit 3,7
      
  • 使用正则:regexp

  • # ^ 以什么开头
    select id,name,job_title from emp where name regexp "^a";
    # $ 以什么结尾
    select id,name,job_title from emp where name regexp "san$";
    # 匹配指定字符内容
    select id,name,job_title from emp where name regexp "i{1}";
    
多表查询

思考:没有主外键关联,是否可以使得两张表产生关联关系?

根据指定条件将两张表中的数据进行合并,然后在合并后的结果表中进行数据的查询

  • 准备数据

  • create table dep(
    	id int primary key,
    	name char(20)
    );
    create table emp(
    	id int primary key auto_increment,
    	name char(20),
    	sex enum("male","female") not null default "male",
    	age int,
    	dep_id int
    );
    
    # 插入数据
    insert into dep values
    (200,'技术'),
    (201,'人力资源'),
    (202,'销售'),
    (203,'运营');
    
    insert into emp(name,sex,age,dep_id) values
    ('ailsa','male',18,200),
    ('lala','female',48,201),
    ('huahua','male',38,201),
    ('zhangsan','female',28,202),
    ('zhaosi','male',18,200),
    ('shenteng','female',18,204)
    ;
    
  • 内连接:

    • 两张表公共的部分,必须同时有,没有就不显示
  • #语法;select * from 表1 inner join 表2 on 合并条件
    select * from emp inner join dep on emp.dep_id = dep.id
    
  • 外连接之左连接

    • 外连接之左连接
      • 以左表为主表,根据左表数据匹配右表,左表数据是全的,而右表若匹配不上则为null
  • select * from emp left join dep on emp.dep_id = dep.id
    
  • 外连接之右连接

    • 以右表为主表,根据右表数据匹配左表,右表数据是全的,而左表若匹配不上则为null
  • select * from emp right join dep on emp.dep_id = dep.id
    
  • 符合条件的多表联查

  • #示例1:找出年龄大于25岁的员工名字以及员工所在的部门名称
    select d.name,e.name from emp as e inner join dep as d on e.dep_id = d.id where age > 25
    
    #示例2:找出年龄大于25岁的员工名字以及员工所在的部门名称,并且以age字段的升序方式显示
    select * from emp as e inner join dep as d on d.id = e.dep_id where age > 25 order by age
    
  • 子查询:子查询是将一个查询语句嵌套在另一个查询语句中

    • 带in关键字的子查询

      • 查询平均年龄在25岁以上的部门名
    • #下述sql返回的就是201和202
      select dep_id from emp group by dep_id having avg(age) > 25
      
      
      #整合后的子查询语句 select name from dep where id in (200,201)
      select name from dep where id in 
      (
      	select dep_id from emp group by dep_id having avg(age) > 25
      )
      
      • 查看技术部员工姓名
    • #获取部门编号200
      select id from dep where name = '技术'
      
      #子查询 select name from emp where dep_id in (200)
      select name from emp where dep_id in (
      	select id from dep where name = '技术'
      )
      
    • 带比较运算符的子查询(比较运算符: =、!=、>、>=、<、<=、<>)

      • 查询大于所有人平均年龄的员工名字与年龄

      • select id,name from emp where age > xx #xx就是所有员工的平均年龄
        #如何获取所有员工的平均年龄
        select avg(age) from emp
        
        #整合后的子查询
        select id,name from emp where age > (select avg(age) from emp)
        
综合练习

在这里插入图片描述

  • 准备数据

  • create table class (
    	cid int PRIMARY KEY,
    	caption varchar(32) not null
    )
    INSERT INTO class VALUES
    (1, '三年二班'), 
    (2, '三年三班'), 
    (3, '一年二班'), 
    (4, '二年九班');
    
    CREATE TABLE teacher(
      tid int PRIMARY KEY,
      tname varchar(32) NOT NULL
    )
    INSERT INTO teacher VALUES
    (1, '张磊老师'), 
    (2, '李平老师'), 
    (3, '刘海燕老师'), 
    (4, '朱云海老师'), 
    (5, '李杰老师');
    
    CREATE TABLE course(
      cid int PRIMARY KEY AUTO_INCREMENT,
      cname varchar(32) NOT NULL,
      teacher_id int NOT NULL,
      FOREIGN KEY (teacher_id) REFERENCES teacher (tid)
    )
    INSERT INTO course VALUES
    (1, '生物', 1), 
    (2, '物理', 2), 
    (3, '体育', 3), 
    (4, '美术', 2);
    
    CREATE TABLE student(
      sid int(11) PRIMARY KEY AUTO_INCREMENT,
      gender char(1) NOT NULL,
      class_id int(11) NOT NULL,
      sname varchar(32) NOT NULL,
      FOREIGN KEY (class_id) REFERENCES class (cid)
    ) 
    INSERT INTO student VALUES
    (1, '男', 1, '理解'), 
    (2, '女', 1, '钢蛋'), 
    (3, '男', 1, '张三'), 
    (4, '男', 1, '张一'), 
    (5, '女', 1, '张二'), 
    (6, '男', 1, '张四'), 
    (7, '女', 2, '铁锤'), 
    (8, '男', 2, '李三'), 
    (9, '男', 2, '李一'), 
    (10, '女', 2, '李二'), 
    (11, '男', 2, '李四'), 
    (12, '女', 3, '如花'), 
    (13, '男', 3, '刘三'), 
    (14, '男', 3, '刘一'), 
    (15, '女', 3, '刘二'), 
    (16, '男', 3, '刘四');
    CREATE TABLE score (
      sid int PRIMARY KEY AUTO_INCREMENT,
      student_id int NOT NULL,
      course_id int NOT NULL,
      num int NOT NULL,
      FOREIGN KEY (course_id) REFERENCES course (cid),
      FOREIGN KEY (student_id) REFERENCES student(sid)
    ) 
    INSERT INTO score VALUES
    (1, 1, 1, 10),
    (2, 1, 2, 9),
    (5, 1, 4, 66),
    (6, 2, 1, 8),
    (8, 2, 3, 68),
    (9, 2, 4, 99),
    (10, 3, 1, 77),
    (11, 3, 2, 66),
    (12, 3, 3, 87),
    (13, 3, 4, 99),
    (14, 4, 1, 79),
    (15, 4, 2, 11),
    (16, 4, 3, 67),
    (17, 4, 4, 100),
    (18, 5, 1, 79),
    (19, 5, 2, 11),
    (20, 5, 3, 67),
    (21, 5, 4, 100),
    (22, 6, 1, 9),
    (23, 6, 2, 100),
    (24, 6, 3, 67),
    (25, 6, 4, 100),
    (26, 7, 1, 9),
    (27, 7, 2, 100),
    (28, 7, 3, 67),
    (29, 7, 4, 88),
    (30, 8, 1, 9),
    (31, 8, 2, 100),
    (32, 8, 3, 67),
    (33, 8, 4, 88),
    (34, 9, 1, 91),
    (35, 9, 2, 88),
    (36, 9, 3, 67),
    (37, 9, 4, 22),
    (38, 10, 1, 90),
    (39, 10, 2, 77),
    (40, 10, 3, 43),
    (41, 10, 4, 87),
    (42, 11, 1, 90),
    (43, 11, 2, 77),
    (44, 11, 3, 43),
    (45, 11, 4, 87),
    (46, 12, 1, 90),
    (47, 12, 2, 77),
    (48, 12, 3, 43),
    (49, 12, 4, 87),
    (52, 13, 3, 87);
    
  • 题目

  • 1、查询所有的课程的名称以及对应的任课老师姓名
    select c.cname,t.tname from course as c inner join teacher as t ON
    	c.teacher_id = t.tid
    
    2、查询学生表中男女生各有多少人
    select gender,count(sid) from student GROUP BY gender 
    
    3、查询物理成绩等于100的学生的姓名
    select t.sname,c.cname,s.num from student as t inner join score as s ON t.sid = s.student_id inner join course as c ON c.cid = s.course_id where c.cname = '物理' and s.num = 100
    		
    4、查询平均成绩大于八十分的同学的姓名和平均成绩
    #查询平均成绩大于八十分的同学的姓名和平均成绩
    #涉及到的字段:成绩,学生名字
    #注意:分组条件为一张表的主键ID,则查询字段可以是该表中的任意字段
    select t.sid,avg(num),t.sname from student as t inner join score as s on s.student_id = t.sid
    GROUP BY t.sid having avg(s.num) > 80
    
    5、查询所有学生的姓名,选课数,总成绩
    select t.sname,count(course_id) as 科目数,sum(s.num) as 总成绩 from student as t inner join score as s on t.sid = s.student_id
    GROUP BY t.sid 
    
    6、 查询姓李老师的个数
    select count(tid) from teacher where tname like '李%'
    
    7、 查询没有报李平老师课的学生姓名
    #select sname from student where sname not in (报李平老师学生的名字)
    
    #报李平老师学生的名字
    #select t1.sname from student as t1 inner join score as s on t1.sid = s.student_id inner join course as c on c.cid = s.course_id inner join teacher as t ON t.tid = c.teacher_id  where t.tname = '李平老师'
    
    #整合的完成操作
    select sname from student where sname not in (select t1.sname from student as t1 inner join score as s on t1.sid = s.student_id
    inner join course as c on c.cid = s.course_id inner join teacher as t ON
    t.tid = c.teacher_id  where t.tname = '李平老师')
    
    8、 查询物理课程比生物课程高的学生的学号
    #1.求出每个学生的物理分数
    select s.student_id,s.num from score as s inner join course as c on s.course_id = c.cid
    where c.cname = '物理'
    #2.求出每个学生的生物分数
    select s.student_id,s.num from score as s inner join course as c on s.course_id = c.cid
    where c.cname = '生物'
    #假设t1就是上面物理对应的表,t2就是上面生物对应的表
    select * from t1 inner join t2 on t1.student_id = t2.student_id 
    where t1.num > t2.num
    #最终的整合
    select t2.student_id from (select s.student_id,s.num from score as s inner join course as c on s.course_id = c.cid
    where c.cname = '物理') as t1 inner join (select s.student_id,s.num from score as s inner join course as c on s.course_id = c.cid
    where c.cname = '生物') as t2 on t1.student_id = t2.student_id 
    where t1.num > t2.num
    
    9、 查询只选修了物理课程或体育课程的学生姓名
    #限制只能要求学生报物理或者报体育其中的一门,不能同时报这两门
    select t.sid,t.sname from student as t inner join score as s on t.sid = s.student_id
    inner join course as c on c.cid = s.course_id
    where c.cname = '物理' or c.cname = '体育'
    GROUP BY t.sid having count(c.cid) < 2
    
    10、查询挂科超过两门(包括两门)的学生姓名和班级id
    select s.sname,count(s1.sid) 个数 from student s
    join score s1 on s.sid = s1.student_id
    where num < 60 group by sname having count(s1.sid)>=2;
    
    11、查询选修了所有课程的学生姓名
    #查询选修了所有课程的学生姓名
    select t.sname from student as t inner join score as s on t.sid = s.student_id
    GROUP BY t.sid having count(s.course_id) = 所有科目的数量
    #查询所有科目的数量
    select count(cid) from course
    #整合
    select t.sname from student as t inner join score as s on t.sid = s.student_id
    GROUP BY t.sid having count(s.course_id) = (select count(cid) from course
    )
    12、查询李平老师教的课程的所有学生(id)的成绩记录
    select s.student_id,c.cname,s.num from score s
    left join course c on s.course_id = c.cid
    left join teacher t on t.tid = c.teacher_id
    where t.tname = "李平老师";
    
    
    13、查询全部学生都选修了的课程号和课程名
    select c.cid,c.cname from score as s inner join course as c ON
    s.course_id = c.cid GROUP BY c.cid 
    having count(course_id) = (select count(sid) from student)
    
    14、查询每门课程被选修的次数
    select c.cname,count(c.cid) from score as s inner join course as c ON
    s.course_id = c.cid GROUP BY c.cid 
    
    
    15、查询只选修了一门课程的学生姓名和学号
    select t.sname,t.sid from student as t inner join score as s on
    t.sid = s.student_id GROUP BY student_id HAVING
    count(s.course_id) = 1
    
    16、查询所有学生考出的成绩并按从高到低排序(成绩去重)
    #查询所有学生考出的成绩并按从高到低排序(成绩去重)
    #DISTINCT对某一个查询字段去重
    select DISTINCT num from score ORDER BY num desc
    
    17、查询平均成绩大于85的学生姓名和平均成绩
    select t.sname,avg(num) from student as t inner join score as s on 
    t.sid = s.student_id group by t.sid having avg(num) > 85
    
    18、查询生物成绩不及格的学生姓名和对应生物分数
    select t.sname,num from student as t inner join score as s on t.sid = s.student_id inner join course as c on c.cid = s.course_id where cname = '生物' and num < 60
    19、查询在所有选修了李平老师课程的学生中,这些课程(李平老师的课程,不是所有课程)平均成绩最高的学生姓名
    select t1.sname,avg(num) from student as t1 inner join score as s on t1.sid = s.student_id inner join course as c on c.cid = s.course_id inner join teacher as t on t.tid = c.teacher_id where t.tname = '李平老师' group by t1.sid order by avg(num) desc limit 1
    
    
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

python爬虫学习笔记-SQL学习 的相关文章

随机推荐

  • 移植QT到QNX,QNX开发QT程序,QT图形开发环境搭建

    锋影 e mail 174176320 qq com 根据QT主页上提供的参数 修改4个地方 configure opensource confirm license qpa iconv shared release xplatform b
  • leetcode笔记:26.删除排序数组中的重复项

    package com ko leetcode primaryAlgorithm array 初级算法 数组 1 删除排序数组中的重复项 Author ko Date 2023 6 1 23 55 Version 1 0 public cl
  • Mysql编码问题的折中方案

    在mysql 5 7 26 0ubuntu0 16 04 1 中尝试修改my cnf无果 采用暂时修改编码的方式 设置MySQL变量 set character set database utf8 set character set ser
  • esp01s如何烧录、接线///arduino串口想输出字符串,但是输出了数字

    esp01s与usb转ttl接线 esp01s 连线 usb转ttl 3V3 3V3 GND GND RX TXD TX RXD IO0 GND IO0接地作用是 进入烧录模式 IO0接地之后需要断电 重新上电 完成烧录后需要 断开 IO0
  • 真正的用window.open()代替window.showModalDialog()

    这个问题 纠结了很长时间在网上找到的 记录一下 正文如下 模式窗口太过于局限性 所以我研究了一个完全可以用window open 代替window showModalDialog 的方法 其资料贴在了下面 有两个页面 一个是调用页面 mai
  • greenbow怎样设置服务器无响应,连接到虚拟机超时

    连接到虚拟机超时 内容精选 换一换 通过网线将DES Edge设备10GE光纤口 图1编号7 从左到右第一列的两个光纤口 与应用服务器所在交换机端口进行连接 将DES Edge设备连接到业务网络 建立业务通道 实现DES Edge设备与应用
  • 有多个li标签,每点击一个li标签改变被点击li标签的背景,并且获取改li标签中的数据

    由于在做如下页面的布局时 采用了多个li标签来展现 需要达到的效果是 1 每点击一个选项卡 该选项卡的背景颜色改变 再点击一次就变回本来的颜色 2 支持多选 并且把选中的选项卡数据存入数组 主要用到的方法就是 取到所有的li标签进行循环添加
  • MySQL 教程

    21分钟 MySQL 入门教程 目录 一 MySQL的相关概念介绍 二 Windows下MySQL的配置 配置步骤 MySQL服务的启动 停止与卸载 三 MySQL脚本的基本组成 四 MySQL中的数据类型 五 使用MySQL数据库 登录到
  • jquery 实现超出部分隐藏,鼠标移动上显示全部文字

    css tooltipdiv position absolute border 1px solid 333 background f7f5d1 padding 3px 3px 3px 3px color 333 display none d
  • 动画设计基础-3d max2014 人物POSS随笔

    动画设计基础 3d max2014 人物POSS随笔 拿到一个人物常用poss 选中质心 鼠标单击右键 选择对象属性 显示属性 显示为外框 Ctrl A删除人物原有的POSS动画 在Ctrl S保存在想要的位置 按N记录 复制人物初始状态
  • 14k字长文理解Transformer: Attention Is All You Need(含python代码)

    作者 猛码Memmat 目录 Abstract 1 Introduction 2 Background 3 Model Architecture 3 1 Encoder and Decoder Stacks 3 2 Attention 3
  • Vue中el-table数据项扩展各种类型总结(持续更新)

    目录 前言 一 普通数据处理 el table数据项调用方法处理值 el table数据项动态加不同颜色圆点 el table数据项项使动态el tag 二 其他插槽类型处理 el table数据项加入输入框 el table数据项上传按钮
  • 终于知道为什么我的ButterKnife不管用了

    终于知道为什么我的ButterKnife不管用了 compile com jakewharton butterknife 8 4 0 apt com jakewharton butterknife compiler 8 4 0
  • uni-app学习

    1 摸鱼唠嗑 1 1 加载中的loading框 之前做项目的时候太着急就没做请求时加载的动画效果 今天看官网的时候突然发现有自带的api组件 用的还不错 但是官网也有大写的注意 showToast 和 showLoading 是底层同一个
  • pyqt5 QWidget 如何隐藏右上角的关闭和提示按钮

    在 PyQt5 中 隐藏 QWidget 右上角的关闭按钮 也称为窗口关闭按钮 可以通过修改窗口的窗口标志位 WindowFlags 来实现 具体如下 import sys from PyQt5 QtWidgets import QAppl
  • Matlab深度学习工具箱的使用

    模型背景 输入x为一个有12维的向量 样本数量假设为1000 输出y 为9个不同的类型 想通过神经网络进行分类 数据导入 输入为12维的 即特征值有12个 样本数量为1000个 如果使用Mini Batch的概念 可以将其分为若干个Batc
  • CHATCC流程

    根据
  • Unity之四:辅助脚本

    文章目录 一 朋友的友情帮助 1 1 generate test runner rb 1 2 generate test runner rb接受的选项 1 2 1 includes 1 2 2 suite setup 1 2 3 suite
  • IPV6工作手册

    1 监测当前是否是IPV6网络环境 浏览器访问 http test ipv6 com 2 切换当前电脑到IPV6网络 Mac电脑 3 监测目标网站是否支持IPV6 可使用 国家IPV6发展监测平台 的检测工具 https www china
  • python爬虫学习笔记-SQL学习

    Sql概述 先来看一个例子 小王第一次使用数据库 然后跟数据库来了个隔空对话 其实 我们想一想 mysql是一个软件 它有它自己一套的管理规则 我们想要跟它打交道 就必须遵守它的规则 如果我想获取数据 它自己有一套规则 这个规则就是SQL