• 数据库数据类型与DQL


    不同的数据库管理系统,数据类型不完全一致

    数字类型

    • 整数类型:INT(m)和BIGINT(m)
      m表示数字的长度(位数)
      INT(5):该字段保存一个5位整数。此时该字段存的为数字18,实际存储:00018
      • 浮点类型:DOUBLE(m,n)
        m表示整体数字的位数
        n表示小数的位数
        DOUBLE(5,3):该字段可以保存一个5位数,其中3位是小数。最大可以保存到:99.999
        实际插入数据时如果精度超过了可保存的范围时,会自动进行四舍五入:
        XXX表有一个DOUBLE(5,3)的字段:
        INSERT INTO XXX VALUES(12.8576)此时该字段实际保存的值为:12.858

    字符类型

    • CHAR(n):定长字符串。
      n:长度,单位是字符。CHAR(10),该字段可以存放最多10个字符
      最大长度:255个字符
      表中每条记录该字段在磁盘上占据的空间是固定的,如果实际保存的字符不足指定的长度时,会在后面补充若干个空格来达到长度。
      name CHAR(10)
      INSERT INTO person (name) values('张三'):实际该记录中name的值:'张三 '(后面有8个空格)
      优点:由于长度固定,因此查询速度快
      缺点:磁盘占用存在浪费的情况
    • VARCHAR(n):变长字符串
      n:长度,单位是字节。VARCHAR(10),该字段保存的字符转换的字节最多10个。
      最大长度为:65535个字节
      优点:实际字段值占用多少字节就在磁盘上开辟多少字节。
      缺点:长度不固定,因此查询性能慢
    • TEXT(n):可变长字符
      n:长度,单位是字符。最大值为65535
    • DATE:可以保存年月日
    • TIME:保存时分秒
    • DATETIME:保存年月日时分秒
    • TIMESTAMP: 时间戳,记录UTC时间。从1970-01-01 00:00:00到其表示的时间之间经过的毫秒

    1. CREATE TABLE userinfo(
    2.         id INT,
    3.         name VARCHAR(30),
    4.         birth DATETIME,
    5.         salary DOUBLE(7,2)
    6. )

    插入日期时,可以使用字符串格式,格式应当为:'yyyy-MM-dd hh:mm:ss'

    • MM表示两个数字的"月",mm表示两位数字的"分"
    INSERT INTO userinfo VALUES(1,'张三','1992-08-02 11:23:56',5000.98);

    如果日期类型使用的是DATETIME,那么在不指定时分秒时,默认为00:00:00

    INSERT INTO userinfo VALUES(2,'李四','1989-06-30',9000);

    DATETIME不能忽略年月日

    INSERT INTO userinfo VALUES(3,'王五','13:25:33',12000);

    插入DOUBLE类型数字时,超过精度部分则会四舍五入

    INSERT INTO userinfo VALUES(3,'王五','1986-03-15',6000.857);

    整数部分超过时会报错

    INSERT INTO userinfo VALUES(4,'赵六','1986-03-15',100000);

    DQL

    DQL用于检索表中数据的语言。

    基本语法:

    SELECT 子句
    FROM 子句
    JOIN... ON... 子句
    WHERE 子句
    GROUP BY 子句
    HAVING 子句
    ORDER BY 子句

    一条DQL语句必须包含的两个子句分别为:SELECT子句和FROM子句

    • SELECT 子句用于选定表中的字段,选定的字段会被包含在查询的结果集中
    • FROM 子句用于指定查询的表

    查看student表中所有记录,每条记录所有字段都要展示在结果集中。

    SELECT * FROM student;


    "*"在SELECT子句中表达的意思时查看表中所有字段。

    SELECT子句中可以仅指定个别字段进行查询

    查看每个学生的名字,年龄,性别
    SELECT name,age,gender
    FROM student

    WHERE子句

    WHERE子句可以添加过滤条件,那么此时仅查询出满足该子句过滤条件的记录

    比较运算符:=,>,>=,<,<=,<>

    • 查看所有大队长
      1. SELECT name,job
      2. FROM student
      3. WHERE job='大队长';

    • 查看年龄在30岁以上的老师的名字和年龄(含30岁)
      1. SELECT name,age
      2. FROM teacher
      3. WHERE age>=30;

    在WHERE子句中可以使用OR,AND来连接多个过滤条件

    • AND:与。都为真时才为真
    • OR:或。都为假时才为假

    例如

    • 查看学生中7岁的大队长都有谁?
      SELECT name,age,job
      FROM student
      WHERE age=7 AND job='大队长';
    • 查看7岁的大队长和中队长都有谁?
      AND的优先级高于OR

      SELECT name,age,job
      FROM student
      WHERE age=7 AND job='大队长' OR job='中队长';
      上述SQL查询的语义是:查看7岁的大队长和所有部分年龄的中队长


      通过添加"()"来提高OR的优先级
      实际写法应当是:
      SELECT name,age,job
      FROM student
      WHERE age=7 AND (job='大队长' OR job='中队长');
    • IN(列表) 等于列表之一
      查看职位是大队长,中队长或小队长的学生?

      SELECT name,job
      FROM student
      WHERE job='大队长' OR job='中队长' OR job='小队长';
      等价
      SELECT name,job
      FROM student
      WHERE job IN('大队长','中队长','小队长');
    • NOT IN(列表) 不等于列表中的内容
      查看职位除了大队长,中队长,小队长的其他学生?

      SELECT name,job
      FROM student
      WHERE job<>'大队长' AND job<>'中队长' AND job<>'小队长';
      等价
      SELECT name,job
      FROM student
      WHERE job NOT IN('大队长','中队长','小队长');
    • BETWEEN...AND... 在两者之间
      查看年龄在9到11岁之间的学生都有谁?

      SELECT name,age
      FROM student
      WHERE age>=9 AND age<=11;
      等价
      SELECT name,age
      FROM student
      WHERE age BETWEEN 9 AND 11;
    • DISTINCT 去重操作。去除结果集中指定字段值重复的行。
      DISTINCT关键字必须紧跟在SELECT关键字之后
      查看学校的学生有多少种职位?

      SELECT DISTINCT job
      FROM student;

      可以多字段去重,去除指定的字段值的组合重复的行
      查看学校同年龄同职位都有多少种?(去除年龄与职位组合相同重复的行)

      SELECT DISTINCT age,job
      FROM student;
    • LIKE:模糊查询
      LIKE中有两个通配符
      • _ 下划线表示1个字符
      • % 百分号表示任意个字符(0---多次)

    组合示意

    - %X%    字符中含有X的
    - %X       字符以X结束
    - X%       字符以X开始
    - _X _      在三个字符中第二个字符为X
    - %X_      字符中倒数第二个为X
    - X_Y       三个字符中第一个为X,第三个为Y

    - X%Y    字符中第一个是X,最后一个是Y

    • 查看所有姓张的同学都是谁? 理解为:名字是以"张"开头的。匹配字符应写为:'张%'
      SELECT name
      FROM student
      WHERE name LIKE '张%';
    • 查看名字中含有王的同学都是谁? 匹配字符:'%王%'
      SELECT name
      FROM student
      WHERE name LIKE '%王%';
    • 查看三个字名字且最有一个字是"平"的同学都有谁? 理解:前两个字是任意字符 匹配字符:'__平'
      SELECT name
      FROM student
      WHERE name LIKE '__平';
    • 查看"李"姓的三个字的名字的同学都有谁? 匹配字符:'李__'
      SELECT name
      FROM student
      WHERE name LIKE '李__';
    • 查看职位是"语文什么表"的同学都有谁? 匹配字符:'语文%表'
      SELECT name,job
      FROM student
      WHERE job LIKE '语文%表';
    • 判断NULL值。
      • IS NULL 判断某个字段的值是否为NULL
      • IS NOT NULL 判断某个字段的是不为NULL
      • 不能直接搭配"="或"<>"来判断NULL值!!!

    查看奖金(comm)为空的老师都有谁?
    SELECT name,salary,comm
    FROM teacher
    WHERE comm=NULL;
    上述SQL是查询不到任何数据的!!

    正确写法:
    SELECT name,salary,comm
    FROM teacher
    WHERE comm IS NULL;

     
    查看有奖金的老师都有谁?

    SELECT name,salary,comm
    FROM teacher
    WHERE comm IS NOT NULL;

     
     

    ORDER BY子句排序

    ORDER BY 子句只能是DQL中的最后一个子句(原因是该子句是最后执行的子句)。

    作用:对结果集按照指定字段值的升序或降序进行排序

     排序方式:

    - 升序:ASC 默认不写就是升序
    - 降序:DESC
    - 多字段排序时:会首先按照第一个字段排序,然后当第一个字段值相同的记录中再按照第二个字段排序以此类推

    例:

    - 查看老师的工资排名?    按照工资进行降序(从大到小)

    SELECT name,salary,comm
    FROM teacher
    ORDER BY salary DESC;

    • 查看老师的奖金?按照升序(从小到大)排序
      SELECT name,salary,comm
      FROM teacher
      ORDER BY comm ASC;
      或者
      SELECT name,salary,comm
      FROM teacher
      ORDER BY comm;
    • 按照日期字段排序时,升序为从早到晚
      按照生日从远到近排序学生

      SELECT name,birth
      FROM student
      ORDER BY birth;
    • 按照老师的工资降序后再按照奖金的升序排
      SELECT name,salary,comm
      FROM teacher
      ORDER BY salary DESC,comm;
      如果第一个字段的值没有重复值,则第二个字段排序无效
    • 按照学生的年龄的升序再按照生日的降序排序
      SELECT name,age,birth
      FROM student
      ORDER BY age,birth DESC;

    别名

    别名在SELECT子句中可以被应用于字段上,函数上或表达式上

    别名也可以被应用于其他子句中,比如在FROM子句中为表取别名

    • 查看老师的年薪是多少?
      SELECT name,salary*12
      FROM teacher;
      上述DQL查询结果集中,第二个字段的字段名直接使用是该表达式,可读性差。


      SELECT name,salary*12 sal
      FROM teacher;
      可以为表达式取别名,此时查询结果集第二个字段名会使用该别名。可读性好。
    • 定义别名支持的语法
      1. 字段名 别名
        SELECT name,salary*12 sal FROM teacher;
      2. 字段名 AS 别名
        SELECT name,salary*12 AS sal FROM teacher;
      3. 字段名 AS '别名' AS可以省略
        SELECT name,salary*12 AS 'sal' FROM teacher;
      4. 字段名 AS "别名" AS可以省略
        SELECT name,salary*12 AS "sal" FROM teacher;

    聚合函数

    聚合函数用来统计的。可以将一个查询结果集中的多条记录统计为一条。

    聚合函数:

    • MIN() 求指定字段在结果集中所有记录里的最小值
    • MAX() 求指定字段在结果集中所有记录里的最大值
    • AVG() 求指定字段在结果集中所有记录里的平均值
    • SUM() 求指定字段在结果集中所有记录里值的总和
    • COUNT() 不是对字段值的统计,而是对结果集中记录数的统计。统计结果集的记录数

    聚合函数的使用时,首要任务是先将需要统计的所有记录查询出来,之后再加以统计。

    例:

    • 查看老师的平均工资是多少?
      1. 先列出所有老师的工资
        SELECT salary FROM teacher;
      2. 对salary加上聚合函数,将结果集中该字段值的所有记录统计平均数
        SELECT AVG(salary) FROM teacher;
    • 查看学校老师的最高工资,最低工资,平均工资和工资总和分别是多少?
      SELECT MAX(salary),MIN(salary),AVG(salary),SUM(salary)
      FROM teacher;
    • 查看负责课程编号1的老师的平均工资是多少?
      1. 查看负责课程编号1的老师的工资?
        SELECT salary FROM teacher WHERE subject_id=1;
      2. 对上述结果集应用聚合函数统计结果
        SELECT AVG(salary) FROM teacher WHERE subject_id=1;
    • 查看所有老师的奖金总和和平均奖金是多少?
      聚合函数忽略NULL值,这个在AVG和COUNT中表现最为明显。

      SELECT SUM(comm),AVG(comm)
      FROM teacher;
      上述DQL查询后实在奖金总和基础上除以15得到的平均值,而非18.因为有3个老师奖金为NULL


      可以通过搭配IFNULL来解决:
      SELECT SUM(comm),AVG(IFNULL(comm,0))
      FROM teacher;
    • 查看学校一共多少个老师?
      很多数据库都对COUNT(*)进行过优化,因此统计记录数通常就用它。

      SELECT COUNT(*) FROM teacher;
    • 查看负责课程编号1的老师一共几人?
      SELECT COUNT(*) FROM teacher WHERE subject_id=1;
    • 查看班级编号(class_id)为1的班里有多少个学生?
      SELECT COUNT(*) FROM student WHERE class_id=1;
    • 查看学校年龄最大的大队长生日是哪天?
      寻找student表中所有大队长的生日中距离现在最远的

      SELECT MIN(birth) FROM student WHERE job='大队长';
  • 相关阅读:
    用了那么久的 Java For 循环,你知道哪种方式效率最高吗?
    【STM32】【HAL库】【实用制作】遥控关灯
    Acwing 840. 模拟散列表
    散列查找 ← 线性探测法处理冲突
    EasyExcel3.1.1版本上传文件忽略列头大小写
    sql 14
    串口通信遇到的一个问题。
    use renv with this project & create a git repository
    Java系列技术之JavaScript基础(从入门开始)③
    数据结构课程设计——用单链表存储多项式实现多项式相加(提供源码和报告)
  • 原文地址:https://blog.csdn.net/m0_51041464/article/details/127701286