mysql之连接符函数使用sql顺序以及键约束介绍

文章目录

    • 单表查询
      • 1.格式
      • 2.关键字连接符操作符等
      • 3.分组函数/聚合函数/多行处理函数
    • 2.连接查询
    • 3.进阶类关键字
      • 1. union合并查询结果集
      • 2. limit分页
    • 时间
    • 表的键
    • 存储引擎
    • mysql执行脚本指令
    • 案例sql脚本

单表查询

1.格式

select ...  
from ...
where ...
group by ...
having ...
order by ...

执行顺序:1.from 2.where 3.group by 4.having 5.select 6.order by

1.如果没带聚合函数不能再where条件后使用,可以在having和select处使用

2.正常group by后查询的字段就应该是group by的字段以及一些聚合的字段

3.没写group by默认一张表为一组

4.尽量用where,where无法实现再采取having

5.order by排序,默认升序,asc升序,desc降序(记忆方法a是小就是升,d是大就是降)

6.别名使用as ,as可以忽略,但是原字段和别名之间不应该有逗号,别名名字里有空格应该用引号括起来,当然实际上不应该出现这样的设计以及情况。

2.关键字连接符操作符等

等于= 不等于<>,!= between…and…在什么之间操作符(左边应小于右边),is null 为空 ,and 且 , or 或(优先级小于=,注意括号问题),in(a,b相当与x='a’or x=‘b’) ,not(not like,is not null) ,like(模糊查询,没有%号相当于=,%在哪边就是哪边模糊,两边就是全模糊查询)

操作分组后的聚合函数需使用having,代码样例:

SELECT *,COUNT(*) AS num FROM emp
GROUP BY JOB,DEPTNO
HAVING num > 3

值得注意的是null值进行计算的时候会变为null,所以需要if null函数(字段,0)或者(字段,‘xxx’)

distinct只能出现在字段的最前方,但是可以被聚合函数包裹,去重规律为对后面的所有字段拼接按列拼接后不重复的记录,同时并不会处理Null值

3.分组函数/聚合函数/多行处理函数

count():算条数,count(*)不为空的行数,因为存在主键不为空,实际就是展示所有行记录,而count(字段)则是计算不为空的字段

sum():括号里填字段,对非空记录进行求和

avg():括号里填字段,对非空记录进行求平均数

max():括号里填字段,获取最大值

min():括号里填字段,获取最小值

2.连接查询

1.需要从其他表获取值,联合展示即为连接查询

2.连接查询语法分类:

SQL92: 1992年出现的语法

​ 缺点:结构不清晰,表连接条件,和后期进一步筛选的条件,糅杂在一起

SQL99: 1999年出现的语法

​ 连接条件与筛选条件分离,即变为join … on … where的这种形式,比较清晰

3.连接方式

​ 内连接:1.等值连接

​ 2.非等值连接

​ 3.自连接

​ 外连接:

​ 左外连接(左连接)

​ 右外连接(右连接)

​ 全连接

4.笛卡尔积

当两个表连接的时候没有进行条件约束,记录数会变成:行*行,所以要加约束条件避免增加表的连接次数

5.内连接

等值连接

SELECT 
	e.*,d.DNAME,d.LOC
FROM
emp e
JOIN 
dept d
ON e.DEPTNO = d.DEPTNO

查薪资在什么级别范围,非等值连接

SELECT 
	e.ENAME,e.SAL,s.GRADE
from 
 emp e
JOIN
 salgrade s
 on e.SAL>s.LOSAL and e.SAL

自连接,查询员工以及其领导的名字(值得注意的是这种连接方式,如果没有等值是无法显示的比如没有上级领导)

SELECT
	e.EMPNO,e.ENAME,e.MGR,em.ENAME as MRGNAME
FROM 
emp e 
JOIN 
emp em
ON
e.MGR = em.EMPNO

6.外连接(left join以及right join)

SELECT 
 e.ENAME,d.DNAME
FROM
emp e
left JOIN
dept d
on e.DEPTNO = d.DEPTNO
SELECT 
 e.ENAME,d.DNAME
FROM
emp e
RIGHT JOIN
dept d
on e.DEPTNO = d.DEPTNO

区别在于有主次关系,哪边连接即哪边全表拼上另一边进行匹配

7.多表连接格式

select ... from a join b on a,b表条件 join c on 前面的表和c表的条件 join d on 前面的表和d表的条件

如查询员工的名字,部门名,薪资,薪资等级等

SELECT
 e.ENAME,d.DNAME,s.GRADE
FROM
emp e 
LEFT JOIN dept d ON e.DEPTNO = d.DEPTNO
LEFT JOIN salgrade s ON e.SAL BETWEEN s.LOSAL AND s.HISAL

全连接:FULL JOIN 即左右的空值都会并上去,一般不使用

8.子查询

  • 什么是子查询

    • select语句中嵌套select语句,被嵌套的select语句称为子查询
    • 子查询都可以出现在哪里呢?
      • select …(select) from where …(select)
  • where条件子查询

    ​ 案例:找出比最低工资高的员工姓名和工资

    SELECT 
    	e.ENAME,e.SAL
    FROM emp e
    WHERE e.SAL > (SELECT MIN(emp.SAL) as mini FROM emp)  
    
  • from子句作为表的子查询

    • 注意:from后面的子查询,可以将子查询的查询结果当做一张临时表

    案例:找出每个岗位的平均工资(按岗位分组求平均值)

    SELECT
    	t.*,s.GRADE
    FROM
    	(SELECT JOB,AVG(SAL) AS salavg FROM emp GROUP BY JOB)  t
    JOIN salgrade s ON  t.salavg  BETWEEN s.LOSAL AND s.HISAL
    

    上面的sql注意子表中的聚合函数需要其别名直接t.AVG(SAL)是不行的,不符合语法,因为会被认为函数,而聚合函数是后执行的

  • select后面的子查询

    值得注意的是这里select子查询,返回的条件只能是一个字段以及一个值,为了不要出现错误可以使用limit)

SELECT 
e.ENAME,(SELECT d.DNAME FROM dept d WHERE e.DEPTNO =d.DEPTNO LIMIT 1) as deptname FROM emp e

3.进阶类关键字

1. union合并查询结果集

SELECT ENAME,JOB FROM emp WHERE JOB = 'MANAGER'
UNION
SELECT ENAME,JOB FROM emp WHERE JOB = 'SALESMAN'

虽然以上的语句可以使用or或者in实现,但是如果在表名字不一致情况下,就只能使用union,而且union的速度更快,在减少匹配的次数的情况下,还可以完成两个结果集的拼接。

比如:当 a连接b连接c

a 10条记录

b 10条记录

c 10条记录

匹配的次数是1000

a 连接 b 一个结果集: 10*10 -->100次

a 连接 c 一个结果集: 10*10 -->100次

使用union的话是:100次 + 100次 =200次 ====》乘法变成了加法

union要求在使用的时候要求上下的列数一致,在mysql对于列数据类型没要求,但是oracle的要求是需要一致的

2. limit分页

1.limit使用

SELECT * FROM emp LIMIT 5 
SELECT * FROM emp LIMIT 0,5

两个结果是一致的limit默认是startIndex,length,如果只有一个参数即去前面多少条的意思,startIndex是起始下标

SELECT * FROM emp LIMIT 3,5

上面即为实际的第4-9(4+5)的记录

2.通用分页

每页显示3条记录

第1页: limit 0,3  [0,1,2]

第2页: limit 3,3  [3,4,5]

第3页: limit 6,3  [6,7,8]

第4页: limit 9,3  [9,10,11]

根据上述规律得,每页显示pageSize 条记录

第pageNO页的记录公式为: limit((pageNO - 1) *pageSize ,pageSize )

当然有些前端或者后端的分页插件已经处理了-1这个事情所以编写代码的时候注意一下。

时间

1.介绍

str_to_date:将字符串varchar转为date类型

date_format:将date类型转换成varchar类型

mysql的日期格式

%Y 年

%m 月

%d 日

%h 时

%i 分

%s 秒

2.示范语句

插入日期

INSERT INTO t_user(id,name,birth) VALUES ('1','zhangsan',STR_TO_DATE('1990-10-01','%Y-%m-%d')) 
SELECT DATE_FORMAT(HIREDATE,'%Y-%m-%d') FROM emp

如果mysql的类型是date,如果传入的字符串是’1990-10-01’这种形式可以不使用str_to_date也可以。实际上mysql的date存储默认就是讲date转为’1990-10-01’(’%Y-%m-%d’)这种形式字符串存储

3.datetime

date是短日期,年月日,默认格式 %Y-%m-%d

datetime是长日期,年月日时分秒 %Y-%m-%d %h:%i:%s(中间的空格数不影响)

CREATE TABLE t_user(
	id int,
	name VARCHAR(32),
	birth date,
	create_time datetime
)
INSERT INTO t_user(id,name,birth,create_time) VALUES ('2','zhangsan','2020-10-01','2020-10-01  10:10:05') 

使用日期的默认字符串形式插入即可

4.时间函数

now()函数,创建的当前时间带有时分秒信息,是datetime类型的

表的键

约束包括哪些?

1.非空约束:not null   

2.唯一性约束:unique

3.主键约束:primary key(简称pk)

4.外键约束:foreign key(简称fk)

5.检查约束:cherk(mysql不支持,oracle支持)

1.在字段后面写not null即为非空约束(列级别约束)

2.唯一unique可以加在字段后面,也可以加在创建语句语句最后独立行unique(‘name’,‘phone’)联合主键 (列级别,表级别约束都可,具体看是否是联合)

3.not null 和unique可联合使用,这样写会默认变成主键约束,mysql中是,Oracle不是

4.primary key可以是列级别的,也可以是表级别的即联合主键primary key(id,name)

即为复合主键,一张表的主键约束只能是一个要不就列级别,要不就复合。

(1)主键值建议int,bigint等数字类型类型

不建议使用varchar来做主键,一般都用数字类型,且定长

(2)设计中:有自然主键和业务主键

​ 自然主键:是一个自然数,和业务没关系

​ 业务主键:主键值和业务紧密关联,例如拿银行卡账号做主键值,这就是业务主键

(3)mysql有自带自增机制:auto_increament

5.外键约束(foreign key,简称fk)

外键约束即给本表的某个字段添加约束,使其的值只能等于关联表的值,即存在主次关系,或者说父子关系,被约束即被加外键的为子,其实数据需遵循父的数据,所有需要先创建父即参考表。创建表以及插入顺序也是先父,再子。

​ 写法: foregin key(字段) references table(字段)

还可以给外键加别名,主表的字段是必须unique级别以上,不一定是主键

(1)在Mysql中取消外键约束: SET FOREIGN_KEY_CHECKS=0;

(2)然后再设置外键约束: SET FOREIGN_KEY_CHECKS=1;

存储引擎

默认存储引擎是InnoDB

默认的编码是:utf8,实际中最好使用utf8mb4

mysql执行脚本指令

source 路径斜杠文件名.sql

案例sql脚本

/*
 Navicat Premium Data Transfer

 Source Server         : localhost
 Source Server Type    : MySQL
 Source Server Version : 50729
 Source Host           : localhost:3306
 Source Schema         : sqltest

 Target Server Type    : MySQL
 Target Server Version : 50729
 File Encoding         : 65001

 Date: 18/07/2021 17:14:44
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for dept
-- ----------------------------
DROP TABLE IF EXISTS `dept`;
CREATE TABLE `dept`  (
  `DEPTNO` int(2) NOT NULL COMMENT '部门编号',
  `DNAME` varchar(14) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '部门名称',
  `LOC` varchar(13) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '地区',
  PRIMARY KEY (`DEPTNO`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of dept
-- ----------------------------
INSERT INTO `dept` VALUES (10, 'ACCOUNTING', 'NEW YORK');
INSERT INTO `dept` VALUES (20, 'RESEARCH', 'DALLAS');
INSERT INTO `dept` VALUES (30, 'SALES', 'CHICAGO');
INSERT INTO `dept` VALUES (40, 'OPERATIONS', 'BOSTON');

-- ----------------------------
-- Table structure for emp
-- ----------------------------
DROP TABLE IF EXISTS `emp`;
CREATE TABLE `emp`  (
  `EMPNO` int(4) NOT NULL COMMENT '员工编号',
  `ENAME` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '员工名',
  `JOB` varchar(9) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '岗位',
  `MGR` int(4) NULL DEFAULT NULL COMMENT '领导编号',
  `HIREDATE` date NULL DEFAULT NULL COMMENT '聘用日期',
  `SAL` double(7, 2) NULL DEFAULT NULL COMMENT '薪资',
  `COMM` double(7, 2) NULL DEFAULT NULL COMMENT '津贴',
  `DEPTNO` int(2) NULL DEFAULT NULL COMMENT '部门编号',
  PRIMARY KEY (`EMPNO`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of emp
-- ----------------------------
INSERT INTO `emp` VALUES (7369, 'SMITH', 'CLERK', 7902, '1980-12-17', 800.00, NULL, 20);
INSERT INTO `emp` VALUES (7499, 'ALLEN', 'SALESMAN', 7698, '1981-02-20', 1600.00, 300.00, 30);
INSERT INTO `emp` VALUES (7521, 'WARD', 'SALESMAN', 7698, '1981-02-22', 1250.00, 500.00, 30);
INSERT INTO `emp` VALUES (7566, 'JONES', 'MANAGER', 7839, '1981-04-02', 2975.00, NULL, 20);
INSERT INTO `emp` VALUES (7654, 'MARTIN', 'SALESMAN', 7698, '1981-09-28', 1250.00, 1400.00, 30);
INSERT INTO `emp` VALUES (7698, 'BLAKE', 'MANAGER', 7839, '1981-05-01', 2850.00, NULL, 30);
INSERT INTO `emp` VALUES (7782, 'CLARK', 'MANAGER', 7839, '1981-06-09', 2450.00, NULL, 10);
INSERT INTO `emp` VALUES (7788, 'SCOTT', 'ANALYST', 7566, '1987-04-19', 3000.00, NULL, 20);
INSERT INTO `emp` VALUES (7839, 'KING', 'PRESIDENT', NULL, '1981-11-17', 5000.00, NULL, 10);
INSERT INTO `emp` VALUES (7844, 'TURNER', 'SALESMAN', 7698, '1981-09-08', 1500.00, 0.00, 30);
INSERT INTO `emp` VALUES (7876, 'ADAMS', 'CLERK', 7788, '1987-05-23', 1100.00, NULL, 20);
INSERT INTO `emp` VALUES (7900, 'JAMES', 'CLERK', 7698, '1981-12-03', 950.00, NULL, 30);
INSERT INTO `emp` VALUES (7902, 'FORD', 'ANALYST', 7566, '1981-12-03', 3000.00, NULL, 20);
INSERT INTO `emp` VALUES (7934, 'MILLER', 'CLERK', 7782, '1982-01-23', 1300.00, NULL, 10);

-- ----------------------------
-- Table structure for salgrade
-- ----------------------------
DROP TABLE IF EXISTS `salgrade`;
CREATE TABLE `salgrade`  (
  `GRADE` int(11) NOT NULL COMMENT '级别',
  `LOSAL` int(11) NULL DEFAULT NULL COMMENT '最低薪资',
  `HISAL` int(11) NULL DEFAULT NULL COMMENT '最高薪资'
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of salgrade
-- ----------------------------
INSERT INTO `salgrade` VALUES (1, 700, 1200);
INSERT INTO `salgrade` VALUES (2, 1201, 1400);
INSERT INTO `salgrade` VALUES (3, 1401, 2000);
INSERT INTO `salgrade` VALUES (4, 2001, 3000);
INSERT INTO `salgrade` VALUES (5, 3001, 9999);

-- ----------------------------
-- Table structure for t_user
-- ----------------------------
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user`  (
  `id` int(11) NULL DEFAULT NULL,
  `name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `birth` date NULL DEFAULT NULL,
  `create_time` datetime(0) NULL DEFAULT NULL
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of t_user
-- ----------------------------
INSERT INTO `t_user` VALUES (1, 'zhangsan', '2020-10-01', '2020-10-01 10:10:05');
INSERT INTO `t_user` VALUES (2, 'zhangsan', '2020-10-01', '2020-10-01 10:10:05');
INSERT INTO `t_user` VALUES (3, 'zhangsan', '2020-10-01', '2021-07-17 22:19:39');

SET FOREIGN_KEY_CHECKS = 1;

你可能感兴趣的:(数据库,mysql)