Mysql——SQL语言入门

news2024/10/5 9:17:42

1.创建数据库表

【1】创建数据库表t_student

(1)创建数据库:

(2)新建查询

(3)创建数据库表

##单行注释
/*
多行注释
多行注释
*/

/*
建立一张用来存储学生信息的表
字段包含学号、姓名、性别、年龄、入学日期、班级、email等信息

*/

##创建数据库表:
CREATE TABLE t_student(
  sno int(6),-- 6显示长度
	sname VARCHAR(10),
	sex char(1),
	age int(3),
	enterdate date,
	classname VARCHAR(10),
	email VARCHAR(15)
);

-- 查看表的结构:展示表的字段的详细信息
desc t_student;


-- 查看表中数据:
SELECT * FROM t_student;


-- 查看建表语句:
SHOW CREATE TABLE t_student;

1.1数据库表列类型

2.对数据的增删改查操作

2.1查询、添加数据

-- 查看表中记录:
SELECT * FROM t_student;


-- 在t_student数据库表中插入数据:
INSERT INTO t_student VALUES(1,'zhangsan','男',18,'2022.5.8','软件1班','123@163.com');
INSERT INTO t_student VALUES(100100100,'zhangsan','男',18,'2022.5.8','软件1班','123@163.com');
INSERT INTO t_student VALUES(100100100,"zhangsan","男",18,"2022.5.8","软件2班","123@163.com");
INSERT INTO t_student VALUES(7,"zhangsan","男",18,NOW(),"软件2班","123@163.com");
-- 如果不是全字段插入数据的话,需要加入字段的名字。
INSERT INTO t_student (sno,sname,sex)VALUES(7,"zhangsan","男");

插入数据的注意事项:

2.2修改、删除数据

-- 查看表中记录:
SELECT * FROM t_student;


-- 在t_student数据库表中插入数据:
INSERT INTO t_student VALUES(1,'zhangsan','男',18,'2022.5.8','软件1班','123@163.com');
INSERT INTO t_student VALUES(100100100,'zhangsan','男',18,'2022.5.8','软件1班','123@163.com');
INSERT INTO t_student VALUES(100100100,"zhangsan","男",18,"2022.5.8","软件2班","123@163.com");
INSERT INTO t_student VALUES(7,"zhangsan","男",18,NOW(),"软件2班","123@163.com");
-- 如果不是全字段插入数据的话,需要加入字段的名字。
INSERT INTO t_student (sno,sname,sex)VALUES(7,"zhangsan","男");


-- 修改表中的数据
UPDATE t_student SET sex = '女';
UPDATE t_student SET sex = '男' WHERE sno = 7;
UPDATE t_student SET classname = 'java01' WHERE sno = 100100100;
UPDATE t_student SET classname = 'JAVA01' WHERE sno = 1;
UPDATE t_student SET age = 29 WHERE classname = 'java01';


-- 删除表中的数据
DELETE FROM t_student WHERE sno = 1;

2.3修改、删除数据库表

-- 查看数据
SELECT * FROM t_student;

-- 修改表的结构
-- 增加一列
ALTER TABLE t_student ADD score DOUBLE(5,2);-- 5是总位数  2是小数位数
UPDATE t_student SET score = 90.589 WHERE sno = 7;

-- 增加一列 放在最前面
ALTER TABLE t_student ADD score DOUBLE(5,2) FIRST;-- 5是总位数  2是小数位数

-- 增加一列 放在sex列的后面
ALTER TABLE t_student ADD score DOUBLE(5,2) AFTER sex;-- 5是总位数  2是小数位数

ALTER TABLE t_student DROP score;-- 删除一列

-- 修改一列
ALTER TABLE t_student MODIFY score FLOAT(4,1);-- modify修改的是列的类型的定义,但是不会改变列的名字
ALTER TABLE t_student CHANGE score score1 DOUBLE(3,1);-- change 修改的是列名和列的类型定义

-- 删除表
DROP TABLE t_student;

3.表的完整性约束

3.1非外键约束

/*
建立一张用来存储学生信息的表
字段包含学号、姓名、性别,年龄、入学日期、班级,emai1等信息
约束:
建立一张用来存储学生信息的表字段包含学号、姓名、性别,年龄、入学日期、班级,emai1等信息
【1】学号是主键  不能为空 + 唯一 ,主键的作用:可以通过主键查到唯一的一条记录
【2】如果主键是整数类型,那么需要自增
【3】姓名不能为空
【4】Email唯一
【5】性别默认值是男
【6】性别只能是男女
【7】年龄只能在18-50之间

*/

CREATE TABLE t_student(
  sno int(6) PRIMARY key auto_increment,
	sname VARCHAR(10) NOT NULL,
	sex char(1) DEFAULT'男' CHECK(sex='男'||sex = '女'),
	age int(3) CHECK(age>=18&&age<=40),
	enterdate date,
	classname VARCHAR(10),
	email VARCHAR(15) UNIQUE
	
);

【1】约束从作用上可以分为两类:

(1)表级约束:可以约束表中任意一个或多个字段。与列定义相互独立,不包含在列定义中;与定义用','分隔;必须指出要约束列的名称。

(2)列级约束:包含在列定义中,直接跟在该列的其他定义之后,用空格分隔,不必指定列名

-- 删除表
DROP TABLE t_student;



CREATE TABLE t_student(
  sno int(6) auto_increment,  -- auto_increment 只能是列级约束
	sname VARCHAR(10) not null, -- not null 只能是列级约束
	sex char(1) DEFAULT '男' ,-- DEFAULT 只能是列级约束
	age int(3),
	enterdate date,
	classname VARCHAR(10),
	email VARCHAR(15),
	CONSTRAINT pk_stu PRIMARY KEY(sno), -- pk_stu 主键约束的名字
	CONSTRAINT ck_stu_sex CHECK(sex='男'||sex='女'),
	CONSTRAINT ck_stu_age CHECK(age>=20&&age<=40),
	CONSTRAINT uq_stu_email UNIQUE(email)
);

-- 添加数据

【2】在创建表以后添加约束(注意,要想一起添加 要在每个句子后面添加分号)

查看表的结构的语句: desc t_student;

3.2外键约束

主表(父表):班级表 - 班级编号 - 主键

从表(子表):学生表 - 编辑编号 - 外键

【2】sql演示:

-- 先创建父表:班级表:
CREATE TABLE t_class(
		cno int(4) PRIMARY KEY auto_increment,
		cname VARCHAR(10) not null,
		croom CHAR(8)
);

-- 添加班级数据
INSERT into t_class value(null,'java001','803教室')
INSERT into t_class value(null,'java002','416教室')
INSERT into t_class value(null,'大数据001','103教室')

-- 可以一次性添加多条记录:
INSERT into t_class value(null,'java001','803教室'),(null,'java002','416教室'),(null,'大数据001','103教室');

-- 查询一下班级表
select * FROM t_class;

-- 创建子表
DROP TABLE t_student;
CREATE TABLE t_student(
  sno int(6) PRIMARY key auto_increment,
	sname VARCHAR(10) NOT NULL,
	classname VARCHAR(10),
	email VARCHAR(15) UNIQUE,
	classno VARCHAR(10) -- 取值参考t_class表中的cno字段,不要求字段名字完全一致,但是长度定义 尽量保证相同。
);

INSERT into t_student (sno,sname,classname)values (null,'张三',1),(null,'李四',1),(null,'王五',3);

-- 查看学生表
SELECT * FROM t_student;


-- 出现问题:
-- 1.我想添加一个学生对应的班级编码为4
INSERT into t_student (sno,sname,classname)values (null,'丽丽',4);
-- 2.想删除班级2
DELETE FROM t_class where cno= 2;

-- 出现问题的原因:因为你的外键约束,没用语法添加进去,现在只是在逻辑上认为班级编号是外键,没有在语法上定义

-- 解决办法:添加外键约束
-- 注意:外键约束只有表级约束,没有列级约束
CREATE TABLE t_student(
  sno int(6) PRIMARY key auto_increment,
	sname VARCHAR(10) NOT NULL,
	classname int(4), -- 取值参考t_class表中的cno字段,不要求字段名字完全一致,但是长度定义 尽量保证相同。
	email VARCHAR(15) UNIQUE,
	classno VARCHAR(10), 
	CONSTRAINT fk_stu_classno FOREIGN KEY (classname) REFERENCES t_class(cno)
);


CREATE TABLE t_student(
  sno int(6) PRIMARY key auto_increment,
	sname VARCHAR(10) NOT NULL,
	classname VARCHAR(10),
	email VARCHAR(15) UNIQUE,
	classno VARCHAR(10),-- 取值参考t_class表中的cno字段,不要求字段名字完全一致,但是长度定义 尽量保证相同。
);
-- 在创建表以后添加外键约束:
ALTER TABLE t_student add CONSTRAINT fk_stu_classno FOREIGN KEY (classname) REFERENCES t_class(cno);

【3】外键策略

-- 先创建父表:班级表:
CREATE TABLE t_class(
		cno int(4) PRIMARY KEY auto_increment,
		cname VARCHAR(10) not null,
		croom CHAR(8)
);

-- 添加班级数据
INSERT into t_class value(null,'java001','803教室'),(null,'java002','416教室'),(null,'大数据001','103教室');

-- 创建子表
CREATE TABLE t_student(
  sno int(6) PRIMARY key auto_increment,
	sname VARCHAR(10) NOT NULL,
	classname int(4), -- 取值参考t_class表中的cno字段,不要求字段名字完全一致,但是长度定义 尽量保证相同。
	CONSTRAINT fk_stu_classno FOREIGN KEY (classname) REFERENCES t_class(cno)
);

INSERT into t_student (sno,sname,classname)values (null,'张三',1),(null,'李四',1),(null,'王五',3);

-- 查看学生表
SELECT * FROM t_student;
-- 查询一下班级表
select * FROM t_class;

-- 删除班级1:如果直接删除的话肯定不行因为有外键约束:
-- 为了解决这个问题加入外键策略:
-- 策略1: no action 不允许操作
-- 通过操作sql来完成: 先把班级2的学生对应的班级 改为null
UPDATE t_student SET CLASSNAME = NULL WHERE CLASSNAME = 1;
DELETE FROM t_class where cno = 1;


-- 策略2:cascade 级联操作:操作主表的时候影响从表的外键信息:
-- 先删除之前的外键约束:
alter TABLE t_student DROP FOREIGN KEY fk_stu_classno;
-- 重新添加外键
alter TABLE t_student add CONSTRAINT fk_stu_classno FOREIGN KEY (classname) REFERENCES t_class(cno) on UPDATE CASCADE ON DELETE CASCADE;


-- 策略3:set null 置空操作:
-- 先删除之前的外键约束:
alter TABLE t_student DROP FOREIGN KEY fk_stu_classno;
-- 重新添加外键
alter TABLE t_student add CONSTRAINT fk_stu_classno FOREIGN KEY (classname) REFERENCES t_class(cno) on UPDATE set NULL ON DELETE set NULL;

-- 注意:
-- 1.策略2 级联操作 和策略3 的删除操作可以混着使用:
alter TABLE t_student add CONSTRAINT fk_stu_classno FOREIGN KEY (classname) REFERENCES t_class(cno) on UPDATE CASCADE ON DELETE set NULL;

-- 2.应用场合:
-- (1)朋友圈删除,点赞和评论都删除 级联操作
-- (2)解散班级,对应的就是置空操作


3.3对DDL和DML的补充

【1】sql展示:

-- 创建表
CREATE TABLE t_student(
  sno int(6) PRIMARY key auto_increment,
	sname VARCHAR(10) NOT NULL,
	sex char(1) DEFAULT'男' CHECK(sex='男'||sex = '女'),
	age int(3) CHECK(age>=18&&age<=40),
	enterdate date,
	classname VARCHAR(10),
	email VARCHAR(15) UNIQUE
);

-- 添加数据
INSERT INTO t_student VALUES (null,'王','男',18,'2020.1.2','java01班','123@789');
INSERT INTO t_student VALUES (null,'雪','男',19,'2020.1.2','java01班','12@789');
INSERT INTO t_student VALUES (null,'健','男',20,'2020.1.2','java01班','1@789');

-- 查看学生表
SELECT * FROM t_student;

-- 添加一个表:快速添加:结构和数据跟t_student都是一致的
CREATE TABLE t_student2
AS
SELECT * FROM t_student;

-- 查看学生表2
SELECT * FROM t_student2;

-- 快速添加:结构跟student一致,数据没有
CREATE TABLE t_student3
AS
SELECT * FROM t_student WHERE 1 = 2;

-- 查看学生表3
SELECT * FROM t_student3;

-- 快速添加:只要部分列,部分数据:
CREATE TABLE t_student4
AS
SELECT sno,sname,age FROM t_student WHERE sno =2;

-- 查看学生表4
SELECT * FROM t_student4;.

-- 删除数据操作:只是清空数据
DELETE FROM t_student;
TRUNCATE TABLE t_student;

【2】delete和truncate的区别:

4.DQL-查询操作

4.1表的准备

准备四张表:dept(部门表),emp(员工表),salgrade(薪资等级表),bonus(奖金表)

-- 创建部门表:属性有部门号,部门名字,LOC 
CREATE table DEPT(
		deptno int(2) not null,
		deptname VARCHAR(14),
		loc VARCHAR(13)
)

-- 给部门表加了一个主键
ALTER TABLE dept 
add CONSTRAINT PK_DEPT PRIMARY KEY (deptno);

-- 创建一个EMP员工表
CREATE table EMP(
		empno int(4) PRIMARY KEY,
		empname VARCHAR(10),
		job VARCHAR(9),
		mgr  int(4),
		hiredate DATE,
		sal DOUBLE(7,2),
		comm DOUBLE(7,2),
		deptno int(2)
)

-- 给员工表加一个外键,关联的是DEPT表中的deptno
ALTER TABLE emp 
add CONSTRAINT FK_deptno 
FOREIGN KEY (deptno)
REFERENCES DEPT (deptno)

-- 创建薪资等级表SALGRADE
CREATE TABLE SALGRADE(
	grade int PRIMARY KEY,
	losal DOUBLE(7,2),
	hisal DOUBLE(7,2)
)

-- 创建奖金表
CREATE TABLE BONUS(
	ename VARCHAR(10),
	job VARCHAR(9),
	sal DOUBLE(7,2),
	comm DOUBLE(7,2)
)

INSERT INTO DEPT(deptno,deptname,loc)
VALUES(10,'ACCOUNTING','NEW YORK');
INSERT INTO DEPT(deptno,deptname,loc)
VALUES(20,'RESEARCH','DALLAS');
INSERT INTO DEPT(deptno,deptname,loc)
VALUES(30,'SALES','CHIGAGO');
INSERT INTO DEPT(deptno,deptname,loc)
VALUES(40,'OPERATIONS','BOSTON');

INSERT INTO EMP(empno,empname,job,mgr,hiredate,sal,comm,deptno)
VALUES(7369,'SMITH','CLERK',7902,'1980-12-17',800,null,20);
INSERT INTO EMP(empno,empname,job,mgr,hiredate,sal,comm,deptno)
VALUES(7499,'ALLEN','SALESMAN',7698,'1981-02-20',1600,300,30);
INSERT INTO EMP(empno,empname,job,mgr,hiredate,sal,comm,deptno)
VALUES(7521,'WARD','SALESMAN',7698,'1981-02-22',1250,500,30);
INSERT INTO EMP(empno,empname,job,mgr,hiredate,sal,comm,deptno)
VALUES(7566,'JONES','MANAGER',7839,'1981-04-02',2975,null,20);
INSERT INTO EMP(empno,empname,job,mgr,hiredate,sal,comm,deptno)
VALUES(7654,'MARTIN','SALESMAN',7698,'1981-09-28',1250,1400,30);
INSERT INTO EMP(empno,empname,job,mgr,hiredate,sal,comm,deptno)
VALUES(7698,'BLAKE','MANAGER',7839,'1981-05-01',2850,null,30);
INSERT INTO EMP(empno,empname,job,mgr,hiredate,sal,comm,deptno)
VALUES(7782,'CLARK','MANAGER',7839,'1981-06-09',2450,null,10);

INSERT INTO SALGRADE(grade,losal,hisal)
VALUES(1,700,1200),(2,1201,1400),(3,1401,2000),(4,2001,3000),(5,3001,9999);

-- 查看表
-- 部门表:dept:department 部门,loc - location 位置
SELECT * FROM DEPT;

-- 员工表:emp:employee 员工 ,mgr:manager 上级领导编号,hiredate:入职日期, common:补助,
-- deptno 外键 参考的是 dept里面的deptno字段
-- mgr 外键 参考的是 自身表emp里面的empno产生了自关联的效果
SELECT * FROM emp;
SELECT * FROM salgrade;
SELECT * FROM bonus;

4.2单表查询

4.2.1最简单的SQL查询

-- 对emp表查询:
SELECT * FROM emp; -- *代表所有数据
-- 显示部分列:
SELECT empno,empname,sal FROM emp;
-- 显示部分行:
SELECT * FROM emp where sal>2000;
-- 显示部分列,部分行:
SELECT empno,empname,sal FROM emp where sal>2000;

-- 起别名:
SELECT empno 员工编号,empname 姓名,sal 工资 FROM emp;
SELECT empno as 员工编号,empname as 姓名,sal as 工资 FROM emp;
-- 在别名中有特殊符号的时候,''或者""不可以省略不写
SELECT empno as '员工编号',empname as "姓名",sal as 工资 FROM emp;

-- 算数运算符:
SELECT empno,empname,sal,sal+1000 涨薪后,deptno FROM emp where sal>2000;
SELECT * FROM emp;

-- 去重操作:
SELECT job FROM emp;
SELECT DISTINCT job FROM emp;
SELECT DISTINCT job,deptno FROM emp;-- 对后面的所有列组合去重,而不是单独的某一列去重

-- 排序:
SELECT * FROM emp order by sal; -- 默认情况下按照升序排列
SELECT * FROM emp order by sal asc;-- 升序
SELECT * FROM emp order by sal desc;-- 降序
SELECT * FROM emp order by sal asc,deptno desc;-- 在工资升序的情况下,deptno按照降序排列

4.2.2where子句

-- 查看emp表
SELECT * FROM emp;

-- where子句:将过滤条件放在where子句的后面,可以筛选/过滤出我们想要的复合条件的数据
-- where子句 + 关系运算符
SELECT * FROM emp WHERE deptno = 10;
SELECT * FROM emp WHERE deptno >= 10;
SELECT * FROM emp WHERE deptno <= 10;
SELECT * FROM emp WHERE deptno <> 10;-- 不等于
SELECT * FROM emp WHERE deptno != 10;-- 不等于
SELECT * FROM emp WHERE job ='clerk';-- 默认情况下不区分大小写
SELECT * FROM emp WHERE BINARY job ='clerk';-- binary区分大小写
SELECT * FROM emp WHERE BINARY hiredate ='1981-12-25';


-- where子句 +逻辑运算符 and
SELECT * FROM emp where sal>1500 and sal< 2500;-- (1500,3000)
SELECT * FROM emp where sal>1500 && sal< 2500;-- (1500,3000)
SELECT * FROM emp where sal>1500 and sal< 2500 ORDER BY sal;
SELECT * FROM emp where BETWEEN 1500 and 3000  ORDER BY sal;-- [1500,3000]

-- where子句 +逻辑运算符 or
SELECT * FROM emp where deptno = 10 or deptno = 20;
SELECT * FROM emp where deptno = 10 || deptno = 20;
SELECT * FROM emp where deptno in (10,20) ;

-- where子句 + 模糊查询
-- 查询名字中带A的员工   -- %代表任意多个字符 0,1,2,......
SELECT * FROM emp WHERE empname LIKE '%A%';
-- 这个_代表任意一个字符
SELECT * FROM emp WHERE empname LIKE '_A%';
SELECT * FROM emp WHERE empname LIKE '__A%';

-- 关于null的判断:
SELECT * FROM emp WHERE comm is null;
SELECT * FROM emp WHERE comm is not null;

-- 关于小括号的使用:
SELECT * FROM emp WHERE (deptno = 10 or deptno = 20) and sal >2000;
SELECT * FROM emp WHERE deptno = 10 or deptno = 20 and sal >2000;-- 先and 再 or and 的优先级比or要高

4.2.3函数

PS:除了多行函数(max,min,count,sum,avg)除了这五个以外,都是单行函数

4.2.3.1单行函数

-- 单行函数包含:
-- 1.字符串函数:substring字符串截取,2:从字符下标2开始,3:截取长度3   (下标从1开始)
SELECT empname,length(ename),substring(empname,2,3) FROM emp;
-- 2.数值函数:abs取绝对值 ceil向上取整 floor向下取整 round四舍五入
SELECT abs(-5),ceil(5.3),FLOOR(5.9),ROUND(3.14) FROM DUAL; -- dual实际上是一个伪表
SELECT abs(-5) 绝对值,ceil(5.3)向上取整,FLOOR(5.9)向下取整,ROUND(3.14)四舍五入; -- 如果没有where条件的话,from dual可以省略不写
SELECT ceil(sal) FROM emp;
SELECT 10/3,10%3,MOD(10,3);
-- 3.日期和时间函数
SELECT * FROM emp;
SELECT CURDATE(),CURTIME();-- CURDATE()年月日  CURTIME()时分秒
SELECT NOW(),SYSDATE(),SLEEP(3),NOW(),SYSDATE();-- NOW()返回当前日期和时间  SYSDATE返回该函数执行时的日期和时间
-- NOW()可以表示年月日时分秒,但是插入数据的时候还是要参照表的结构
-- 4.流程函数
-- if相关
SELECT empno,empname,sal,IF(sal>=2500,'高薪','低薪')薪资等级 FROM emp;-- if ELSE 双分支结构
SELECT empno,empname,sal,comm,sal+IFNULL(comm,0) FROM emp;-- 如果comm是null,那么取值为0  -- 单分支
SELECT NULLIF(1,1),NULLIF(1,2); -- 如果value1等于value2,则返回null,否则返回value1
-- case相关:case等值判断
SELECT empno,empname,job,
CASE job
when 'CLERK' then '店员'
else '其他'
end 岗位,
sal FROM emp;
-- case区间判断
SELECT empno,empname,job,
CASE job
when sal<=1000 then 'A'
when sal<=2000 then 'B'
when sal<=3000 then 'C'
else 'D'
end 工资等级,
deptno FROM emp;

-- 5.JSON函数  
-- 6.其他函数 -- DATABASE()当前数据库是啥  USER()使用者是谁  VERSION()对应的数据库的版本
SELECT DATABASE(),USER(),VERSION() ;

4.2.3.2多行函数

-- 单行函数包含:
-- 1.字符串函数:substring字符串截取,2:从字符下标2开始,3:截取长度3   (下标从1开始)
SELECT empname,length(ename),substring(empname,2,3) FROM emp;
-- 2.数值函数:abs取绝对值 ceil向上取整 floor向下取整 round四舍五入
SELECT abs(-5),ceil(5.3),FLOOR(5.9),ROUND(3.14) FROM DUAL; -- dual实际上是一个伪表
SELECT abs(-5) 绝对值,ceil(5.3)向上取整,FLOOR(5.9)向下取整,ROUND(3.14)四舍五入; -- 如果没有where条件的话,from dual可以省略不写
SELECT ceil(sal) FROM emp;
SELECT 10/3,10%3,MOD(10,3);
-- 3.日期和时间函数
SELECT * FROM emp;
SELECT CURDATE(),CURTIME();-- CURDATE()年月日  CURTIME()时分秒
SELECT NOW(),SYSDATE(),SLEEP(3),NOW(),SYSDATE();-- NOW()返回当前日期和时间  SYSDATE返回该函数执行时的日期和时间
-- NOW()可以表示年月日时分秒,但是插入数据的时候还是要参照表的结构
-- 4.流程函数
-- if相关
SELECT empno,empname,sal,IF(sal>=2500,'高薪','低薪')薪资等级 FROM emp;-- if ELSE 双分支结构
SELECT empno,empname,sal,comm,sal+IFNULL(comm,0) FROM emp;-- 如果comm是null,那么取值为0  -- 单分支
SELECT NULLIF(1,1),NULLIF(1,2); -- 如果value1等于value2,则返回null,否则返回value1
-- case相关:case等值判断
SELECT empno,empname,job,
CASE job
when 'CLERK' then '店员'
else '其他'
end 岗位,
sal FROM emp;
-- case区间判断
SELECT empno,empname,job,
CASE job
when sal<=1000 then 'A'
when sal<=2000 then 'B'
when sal<=3000 then 'C'
else 'D'
end 工资等级,
deptno FROM emp;

-- 5.JSON函数  
-- 6.其他函数 -- DATABASE()当前数据库是啥  USER()使用者是谁  VERSION()对应的数据库的版本
SELECT DATABASE(),USER(),VERSION() ;

-- 多行函数
SELECT max(sal),min(sal),count(sal),sum(sal),avg(sal) FROM emp;
-- 多行函数会自动忽略null值
SELECT max(comm),min(comm),count(comm),sum(comm),avg(comm) FROM emp;
-- max(), min(), count() 针对所有类型  sum(),avg() 只针对数值类型有效


-- count -- 计数
-- 统计表的记录数:方式1
SELECT * FROM emp;
SELECT count(*) FROM emp;

-- 方式2
SELECT 1 FROM dual;
SELECT 1 FROM emp;
SELECT count(1) FROM emp;

4.2.4 group by分组和having筛选

【1】group by:用来进行分组

【2】sql展示:

-- 统计各个部门的平均工资
SELECT deptno,avg(sal) FROM emp; -- 字段和多行函数不能同时使用
SELECT deptno,avg(sal) FROM emp GROUP BY deptno ORDER BY deptno desc; -- 字段和多行函数不能同时使用,除非这个字段属于分组


-- 统计各个部门的平均工资
SELECT job,avg(sal) FROM emp GROUP BY job;

【3】having:进行分组后的筛选

【4】sql展示:

-- 统计各个部门的平均工资,只显示平均工资2000以上的  分组以后进行二次筛选
SELECT deptno,avg(sal) FROM emp GROUP BY deptno HAVING avg(sal)>2000;
SELECT deptno,avg(sal) 平均工资 FROM emp GROUP BY deptno HAVING 平均工资>2000;
SELECT deptno,avg(sal) 平均工资 FROM emp GROUP BY deptno HAVING 平均工资>2000 ORDER BY deptno desc;

-- 统计各个岗位的平均工资,除了MANAGER
-- 方法1
SELECT job,AVG(sal) FROM emp where job !='MANAGER' GROUP BY job;
-- 方法2
SELECT job,AVG(sal) FROM emp GROUP BY job HAVING job!='MANAGER';
-- where 在分组前进行过滤的,having是在分组后进行过滤的

4.2.5 单表查询总结

【1】select语句总结

【2】select语句的执行顺序

【3】单表查询练习:

-- 单表查询练习:
-- 列出工资最小值小于2000的职位
SELECT job,MIN(sal) FROM emp GROUP BY job HAVING MIN(sal)<2000;
SELECT * FROM emp;
SELECT * FROM dept;


-- 列出平均工资大于1200元的部门和工作搭配组合
SELECT deptno,job,AVG(sal) FROM emp GROUP BY deptno,job HAVING AVG(sal)>1200 ORDER BY deptno;

-- 统计[人数小于4的]部门的平均工资。
SELECT deptno,AVG(sal) FROM emp GROUP BY deptno HAVING COUNT(deptno)<4;

-- 统计各部门的最高工资,排除最高工资小于3000的部门。
SELECT deptno,MAX(sal) FROM emp GROUP BY deptno HAVING MAX(sal)>=3000;

4.3多表查询

4.3.1交叉连接,自然连接,内连接

-- 查询员工得编号,姓名,部门编号:
SELECT * FROM emp;
SELECT empno,empname,deptno FROM emp;

-- 查询员工得编号,姓名,部门编号,部门名称:
SELECT * FROM emp; -- 14条记录
SELECT * FROM dept; -- 4条记录

-- 多表查询:
-- 交叉链接:cross join
SELECT * 
FROM emp
cross join dept; -- 14*4 = 56条  笛卡尔乘积: 没有实际意义,有理论意义
  
-- 自然链接:natural join 
-- 优点:自动匹配所有的同名列, 同名列只展示一次,简单
SELECT * 
FROM emp
NATURAL join dept;

-- 缺点:查询字段的时候,没有指定字段所属的数据库表,效率低
-- 解决:指定表名
SELECT emp.empno,emp.empname,dept.deptno 
FROM emp
NATURAL JOIN dept;

-- 缺点:表名太长咋办啊
-- 解决:表可以起别名
SELECT e.empno,e.empname,d.deptno 
FROM emp e
NATURAL JOIN dept d;

-- 自然链接natural join 的缺点:自动表中的匹配所有的同名列。但是有时候我们只希望匹配部分同名列
-- 解决:内连接 - using子句
SELECT * 
FROM emp
inner join dept -- inner 内连接
using(deptno);  -- 这里不能写natural join了,这里是内连接

-- using缺点:关联的字段,必须是同名的
-- 解决:内连接的里面的on子句
SELECT * 
FROM emp e
inner join dept d
on (e.aaa = d.bbb);

-- 多表链接查询的类型:
/*
1.交叉链接 cross join 
2.自然链接 natural join 
3.内连接 - using子句
4.内连接 - on子句 
综合看 内连接 - on子句用的最多
*/

-- 条件:
/*
1.筛选条件  where  having 
2.连接条件  on,using,natural,cross
SQL99语法: 筛选条件和连接条件是分开的
*/

4.3.2外连接

-- inner join - on 子句: 显示的是所有匹配的信息

-- 外连接:除了显示匹配的数据之外,还可以显示部门或者全部不匹配的数据
-- 左外连接: left outer join  --左面哪个表的信息,即使不匹配也可以查看出效果
SELECT * 
FROM emp e
left join dept d
on e.deptno = d.deptno;

-- 右外连接: right outer join  --右面哪个表的信息,即使不匹配也可以查看出效果
SELECT * 
FROM emp e
right outer join dept d
on e.deptno = d.deptno ;

-- 全外连接 
SELECT * 
FROM emp e
left join dept d
on e.deptno = d.deptno
union -- 并集 去重 效率低
SELECT * 
FROM emp e
right outer join dept d
on e.deptno = d.deptno;


SELECT * 
FROM emp e
left join dept d
on e.deptno = d.deptno
union all -- 并集 不去重 效率高
SELECT * 
FROM emp e
right outer join dept d
on e.deptno = d.deptno ;

4.3.3三表连接查询

4.3.4自连接

想象成两张表。

4.4子查询

【1】什么是子查询?

一条SQL语句含有多个select

【2】执行顺序:

先执行子查询,再执行外查询

【3】不相关子查询:

子查询可以独立运行,称为不相关子查询。

【4】不相关子查询分类:

根据子查询的结果行数,可以分为单行子查询和多行子查询。

4.4.1不相关子查询

4.4.1.1单行子查询

4.4.1.2多行子查询

4.4.2相关子查询

【1】相关子查询引入

【2】相关子查询的优缺点

5.数据库对象

5.1事务及其特征

事务是用来维护数据库完整性的,它能够保证一系列的MySQL操作要么全部执行,要么全不执行

【1】事务的概念

【2】事务的特性

但是不是所有的操作序列都可以成为事务,要成为事务要满足四个特性,ACID特性

【3】sql展示:

5.2事务并发问题

【1】脏读

【2】不可重复读

【3】幻读

【4】不可重复读和幻读的区别:

不可重复读的重点是修改,幻读的重点在于新增或者删除。

解决不可重复读的问题只需要锁住满足条件的行,解决幻读需要锁住表。

5.2事务隔离级别

为了解决事务的并发问题,引入了事务的并发级别。

5.3视图

【3】sql展示:

5.3存储过程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/544120.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

chatgpt赋能Python-python30_3__2

Python30-3**2 – 强大的Python解释器的介绍 Python30-32是一个开源的Python解释器&#xff0c;其名称表示30乘以3的平方&#xff0c;即2700&#xff0c;意味着它是Python 3的改进版本。Python30-32由一群志愿者开发&#xff0c;旨在提供一个高效、强大、易于使用的编程工具&a…

【ChatGPT】无需注册,无需科学上网,无需人工验证的速度超快的 ChatGPT

文章目录 一、ChatGPT介绍二、使用ChatGPT时经常遇到的一些问题三、一个让你呼吸顺畅的 ChatGPT 一、ChatGPT介绍 ChatGPT&#xff0c;全称聊天生成预训练转换器&#xff08;英语&#xff1a;Chat Generative Pre-trained Transformer&#xff09;&#xff0c;是OpenAI开发的人…

【数学建模】矩形桌子能放平(初等模型)

把一把四只脚的椅子往不平的地面上一放&#xff0c;通常只有三只脚着地&#xff0c;放不稳&#xff0c;然而只要稍挪动几次&#xff0c;就可以四脚着地&#xff0c;放稳了。如何解释这种现象&#xff1f; 1 模型假设 椅子四条腿一样长&#xff0c;椅脚与地面接触可视为一个点&…

【MCS-51】定时器原理

时间是我们设计功能模块时一个十分重要的输入或者衡量指标&#xff0c;而51单片机中就为我们提供了两个时域上的模块&#xff1a;定时器和计数器。它们可以帮助我们实现一些非实时性的功能&#xff1a;延迟、计时以及定时等。其中51单片机有两个16位的模块&#xff1a;定时器0&…

SCI论文总重复率29%,单篇重复达到了4%,请问可以了吗?

&#x1f449;&#x1f3fb;有小伙伴问&#xff1a;SCI论文查重29&#xff05;&#xff0c;有一篇跟导师之前发表的论文重复达到了4&#xff05;&#xff0c;请问可以吗&#xff1f;之前重复率是37&#xff05;&#xff0c;改了好久才改下来&#xff0c;但是感觉29&#xff05;…

劝你别去外包,干了三年,感觉废了一半....

先说一下自己的情况&#xff0c;大专生&#xff0c;19年通过校招进入杭州某个外包软件公司&#xff0c;干了接近3年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落! 而我已经在一个企业干了3年的功…

UWB技术在人员管理上的应用

UWB技术在人员管理上的应用 UWB 技术是一种新型的无线通信技术&#xff0c;主要用于低功耗数据快速传输以及室内静止或移动物体/人的定位跟踪与导航。在人员管理方面&#xff0c;UWB 技术有着广泛的应用&#xff0c;可以实现对人员的实时定位管理、历史轨迹追溯、电子围栏、巡…

ipa文件怎么安装到iPhone手机上?

无需越狱帮你把ipa文件安装到苹果手机上 E86苹果签名简介&#xff1a;点击可查看 很多人都知道apk文件是安卓的app应用程序文件名&#xff0c;但有人知道苹果ios的app应用程序app是什么样的文件名吗&#xff1f; 是ipa文件。 ipa文件由三个部分组成&#xff0c;payload目录下…

基于短核苷酸序列频率构建细菌系统发育树

谷禾健康 目前&#xff0c;原核生物的系统发育分类依赖于16S rRNA基因序列&#xff0c;这种序列在细菌中广泛存在且高度保守&#xff0c;但即使16S rDNA测序的结果显示某些细菌间序列相似性≥99%&#xff0c;但它们仍然不能被归为同一物种。因为基因序列中的一些保守区域并不一…

Doxygen源码分析: 子目录简要介绍

2023-05-18 23:56:46 ChrisZZ imzhuofoxmailcom Hompage https://github.com/zchrissirhcz 文章目录 1. doxygen 版本2. doxygen 目录结构.git 目录.github 目录workflows/build_cmake.ymlworkflows/coverity.ymlworkflows/docer_publish.yml addon 目录doxmlparser 目录doxyap…

金币商城功能迭代. 使用版本号乐观锁解决数据的并发修改问题

前言. 公司的商城模块嵌在微信公众号里面, 商城里面除了少量的现金业务, 大头在金币业务里面, 商城本来就是用来增加客户粘度的, 金币是客户通过某些行为免费获得如注册, 绑定,推荐等 需求. 金币方面之前的设计: 1.金币只有一个流水表,消费为负,获取为正 2.并且…

常用的表格检测识别方法 - 表格区域检测方法(下)

——书接上文 Training 半监督网络的训练分两步进行&#xff1a;a)对标记数据独立训练学生模块&#xff0c;由教师模块生成伪标签&#xff1b;b)结合两个模块的训练&#xff0c;得到最终的预测结果。 伪标签框架 实验 数据集&#xff1a; TableBank是文档分析领域中用于表识别…

Beats:如何在 Docker 容器中运行 Filebeat

今天在这篇博客中&#xff0c;我们将学习如何在容器环境中运行 Filebeat。 为了快速了解 Filebeat 是做什么用的&#xff1a; Filebeat用于转发和集中日志数据它重量轻&#xff0c;小型化&#xff0c;使用的资源更少它作为代理安装在你的服务器上它监视来自指定位置的日志文件…

腾讯云EdgeOne为什么能让客户降本增效?

随着数字化时代的来临&#xff0c;各类线上互动场景不断出现&#xff0c;并成为人们日常工作生活中的一部分。然而&#xff0c;基于互联网提供线上娱乐、线上办公、线上购物等服务的企业&#xff0c;在复杂的全球网络环境下会遇到网络延迟不稳定的情况&#xff0c;海外环境更多…

QGIS安装与简单使用流程

QGIS工具是我们地图业务领域比用的工具之一&#xff0c;理论就先不介绍了&#xff0c;今天主要介绍安装使用等基本操作&#xff1a; 一、下载安装 1、官网下载 Download QGIS 显示页面&#xff1a; 可以选择不同版本。我们以3.28为例&#xff0c;点击进入&#xff1a; 点击…

【hive】hive order、sort、distribute、cluster by区别与联系

​ 1、order by hive中的order by 会对查询结果集执行一个全局排序&#xff0c;这也就是说所有的数据都通过一个reduce进行处理的过程&#xff0c;对于大数据集&#xff0c;这个过程将消耗很大的时间来执行。 2、sort by hive的sort by 也就是执行一个局部排序过程。这可以…

怎么将heic格式转化jpg,5种方法立马学

将HEIC格式转换为JPG格式是非常必要的。首先&#xff0c;HEIC&#xff08;.heic&#xff09;格式是苹果最新推出的图像格式。与JPEG相比&#xff0c;HEIC可以存储更多的图像信息&#xff0c;同时还支持透明度、深度和动态范围等功能。但由于HEIC格式相对较新&#xff0c;许多设…

Rust之泛型、特性和生命期(二):通用数据类型

开发环境 Windows 10Rust 1.69.0 VS Code 1.78.2 项目工程 这里继续沿用上次工程rust-demo 通用数据类型 我们使用泛型来为函数签名或结构等项目创建定义&#xff0c;然后我们可以将其用于许多不同的具体数据类型。让我们首先看看如何使用泛型来定义函数、结构、枚举和方法。…

27K 入职字节的那天,我哭了····

先说一下自己的个人情况&#xff0c;计算机专业&#xff0c;18年本科毕业&#xff0c;一毕业就进入了“阿里”测试岗(进去才知道是接了个阿里外包项目&#xff0c;可是刚毕业谁知道什么外包不外包的)。 更悲催的是&#xff1a;刚入职因为家里出现一些变故&#xff0c;没有精力…

【软件测试】Python自动化软件测试算是程序员吗?

今天早上一觉醒来&#xff0c;突然萌生一个念头&#xff0c;【软件测试】软件测试算是程序员吗&#xff1f;左思右想&#xff0c;总感觉哪里不对。做了这么久的软件测试&#xff0c;还真没深究过这个问题。 基于&#xff0c;内事问百度的准则&#xff1a; 结果…… 我刚发出软…