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

数字类型

  • 整数类型: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到其表示的时间之间经过的毫秒

CREATE TABLE userinfo(
        id INT,
        name VARCHAR(30),
        birth DATETIME,
        salary DOUBLE(7,2)
)

插入日期时,可以使用字符串格式,格式应当为:'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子句可以添加过滤条件,那么此时仅查询出满足该子句过滤条件的记录

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

  • 查看所有大队长
SELECT name,job
FROM student
WHERE job='大队长';
  • 查看年龄在30岁以上的老师的名字和年龄(含30岁)
SELECT name,age
FROM teacher
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='大队长';