MySQL面试篇章——MySQL核心SQL(基本语法)

文章目录

结构化查询语句SQL

SQL是结构化查询语言(Structure Query Language),它是关系型数据库的通用语言

SQL主要可以划分为3个类别:

  • DDL(Data Definition Language)语句

    数据定义语言,这些语句定义了不同的数据库、表、列、索引等数据库对象的定义。常用的语句关键字主要包括 create、drop、alter等。

  • DML(Data Manipulation Language)语句

    数据操纵语句,用于添加、删除、更新和查询数据库记录,并检查数据完整性,常用的语句关键字主要包括 insert、delete、update 和select 等。

  • DCL(Data Control Language)语句

    数据控制语句,用于控制不同的许可和访问级别的语句。这些语句定义了数据库、表、字段、用户的访问权限和安全级别。主要的语句关键字包括 grant、revoke 等。

库操作

  • 查询数据库
mysql 复制代码
show databases;
  • 创建数据库
mysql 复制代码
create database ChatDB;
  • 删除数据库
mysql 复制代码
drop database ChatDB;
  • 选择数据库
mysql 复制代码
use ChatDB;

表操作

  • 查看表
mysql 复制代码
show tables;
  • 创建表
mysql 复制代码
CREATE TABLE user (
    id BIGINT UNSIGNED PRIMARY KEY NOT NULL AUTO_INCREMENT COMMENT 'id号',
    name VARCHAR(50) UNIQUE NOT NULL COMMENT '姓名',
    age TINYINT UNSIGNED NOT NULL COMMENT '年龄',
    sex ENUM('M', 'W') NOT NULL COMMENT '性别,M男性,W女性'
) ENGINE=INNODB DEFAULT CHARSET=utf8;
  • 查看表结构
mysql 复制代码
desc user;
  • 查看建表SQL(可以查看索引、外键等情况)
mysql 复制代码
show create table user\G;
  • 删除表
mysql 复制代码
drop table user;

CURD 操作

insert 增加

mysql 复制代码
# 添加表数据
INSERT INTO user(name, age, sex) VALUES('zhangsan', 18, 'M');
INSERT INTO user(name, age, sex) VALUES('lisi', 19, 'W');
INSERT INTO user(name, age, sex) VALUES('wangwu', 20, 'M');
INSERT INTO user(name, age, sex) VALUES('zhaoliu', 21, 'W');
INSERT INTO user(name, age, sex) VALUES('qianqi', 22, 'M');

INSERT INTO user(name, age, sex) VALUES('zhangsan', 18, 'M'),('lisi', 19, 'W'),('wangwu', 20, 'M'),('zhaoliu', 21, 'W'),('qianqi', 22, 'M');

扩展:两种添加方式的不同

每次的 insert 操作都会有一个数据库连接操作,是占用资源的,一次连接完成的事情肯定比多次连接完成的事情所花费的时间短

update 修改

myqsl 复制代码
update user set age = 23 where name = 'zhangsan';
update user set age = age + 1 where id = 3;

delete 删除

mysql 复制代码
delete from user where age=23;
delete from user where age between 20 and 22;
delete from user;

select 查询

mysql 复制代码
select * from user;
select id, nickname, name, age, sex from user;
select id, name from user;
select id, nickname, name, age, sex from user where sex = 'M' and age >= 20 and age <= 25;
select id, nickname, name, age, sex from user where sex = 'M' and age between 20 and 25;
select id, nickname, name, age, sex from user where sex = 'W' or age >= 22;

去重 distinct

mysql 复制代码
select distinct name from user;

空值查询

  • is [not] null
mysql 复制代码
select * from user where name is null;

union 合并查询

  • 一句话:连接两个select查询的SQL语句(全查)
mysql 复制代码
SELECT country FROM Websites UNION ALL SELECT country FROM apps ORDER BY country;

注意:union 默认去重,不用修饰distinct,all显示所有重复值

带 in 子查询

  • [not] in (元素1,元素2,...,元素n)
mysql 复制代码
select * from user where id in (10, 20, 30, 40, 50)
select * from user where id not in (10, 20, 30, 40, 50)
select * from user where id in (select stu_id from grade where average >= 60.0)

分页查询

mysql 复制代码
select id, nickname, name, age, sex from user limit 10;
select id, nickname, name, age, sex from user limit 2000,10;

select * from user limit N offset M;

explain进行分析:查看SQL语句的执行计划
  • 测试代码(自动生成2000000条数据)【测试分页,测试explain所用】
mysql 复制代码
# 修改SQL结束的符号
delimiter $

Create Procedure add_t_user (IN n INT)
BEGIN
DECLARE i INT;
SET i=0;

WHILE i<n DO
INSERT INTO t_user VALUES(NULL,CONCAT(i+1,'@fixbug.com'),i+1);
SET i=i+1;
END WHILE;
END$

delimiter ;

call add_t_user(2000000);

面试题:分页的效率低吗?为什么低?怎么修改呢?

低,pageNum的偏移所花费的性能,要先偏移到对应的位置,在进行分页拿去后面的数据记录

修改:添加索引,通过where筛选条件进行偏移

mysql 复制代码
select * from t_user limit 1500000, 3;

select * from t_user where id >= 1500000 limit 3;
  • 查询的情况
  • 使用explain指令进行分析
  • 可以发现由于用了索引,所以速率快
  • 注意:limit的性能优化explain看不到,所以rows还是多的,并且是using where不是using index,explain不展示MySQL Server所进行的优化,所以看这个也没啥意思,主要还是看他们的一个执行速率

排序 order by

mysql 复制代码
select id,nickname,name,age,sex from user where sex='M' and age>=20 and age<=25 order by age asc;
select id,nickname,name,age,sex from user where sex='M' and age>=20 and age<=25 order by age desc;

**扩展:**order by 查询特别慢,查看explain进行分析,发现是Using filesort,所以给排序列或者查询列添加索引

分组 group by

mysql 复制代码
select sex from user group by sex;
select count(id), sex from user group by sex;
select count(id), age from user group by age having age>20;

**扩展:**group by 查询慢,explain 分析发现是 Using temporary,即产生了一个临时表,因此最好给分组列添加索引

笔试实践题

下表bank_bill是某银行代缴话费的主流水表结构:

字段名 描述
serno 流水号
date 交易日期
accno 账号
name 姓名
amount 金额
brno 缴费网点

1、统计表中缴费的总笔数和总金额

2、给出一个sql,按网点和日期统计每个网点每天的营业额,并按照营业额进行倒序排序

mysql 复制代码
CREATE TABLE bank_bill (
    serno BIGINT UNSIGNED PRIMARY KEY NOT NULL AUTO_INCREMENT,
    date DATE NOT NULL,
    accno VARCHAR(100) NOT NULL,
    name VARCHAR(50) NOT NULL,
    amount DECIMAL(10, 1) NOT NULL,
    brno VARCHAR(150) NOT NULL
 );
 
 INSERT INTO bank_bill VALUES
 ('101000', '2021-3-1', '111', 'zhang', 100, '高新区支行'),
 ('101001', '2021-3-1', '222', 'liu', 200, '碑林区支行'),
 ('101002', '2021-3-1', '333', 'gao', 300, '高新区支行'),
 ('101003', '2021-3-1', '444', 'lian', 150, '雁塔区支行'),
 ('101004', '2021-3-1', '555', 'lan', 360, '雁塔区支行'),
 ('101005', '2021-3-1', '666', 'wang', 300, '碑林区支行'),
 ('101006', '2021-3-1', '777', 'wei', 500, '碑林区支行'),
 ('101007', '2021-3-2', '444', 'lian', 150, '雁塔区支行'),
 ('101008', '2021-3-2', '555', 'lan', 360, '雁塔区支行'),
 ('101009', '2021-3-2', '666', 'wang', 300, '碑林区支行'),
 ('101010', '2021-3-3', '777', 'wei', 500, '碑林区支行');

连接查询

  • 连接表时需要在每个表中选择一个字段,并对这些字段的值进行比较,值相同的两条记录将合并为一条。连接表的本质就是将不同表的记录合并起来,形成一张新表。当然,这张新表只是临时的,它仅存在于本次查询期间
  • SQL 先根据 ON 生成一张临时表,然后再根据 WHERE 对临时表进行筛选

内连接查询

mysql 复制代码
select s.uid, s.name, s.age, s.sex, e.score from student s inner join exame e on s.uid = e.uid where e.uid = 1 and e.cid = 2;

注意:on s.uid = e.uid 会区分大表和小表,是按照记录的个数(数据量)区分

数量多的为大表,小的为小表

小表永远是整表扫描,然后去大表搜索

从 student 表中取出所有的s.uid,然后拿着这些uid去exame大表中搜索

有 where 会进行where的过滤,在划分大小表,来决定哪个整表扫描

对于inner join内连接,过滤条件写在where的后面和on连接条件里面,效果是一样的

外连接查询

左连接查询

mysql 复制代码
# 把left这边的表所有的数据显示出来,在右表中不存在相应数据,则显示NULL
select a.*, b.* from student a left join exame b on a.uid = b.uid;


右连接查询

mysql 复制代码
# 把right这边的表所有的数据显示出来,在左表中不存在相应数据,则显示NULL
select a.*, b.* from student a right join exame b on a.uid = b.uid;
相关推荐
Hacker_LaoYi1 小时前
SQL注入的那些面试题总结
数据库·sql
LCG元2 小时前
【面试问题】JIT 是什么?和 JVM 什么关系?
面试·职场和发展
Hacker_LaoYi3 小时前
【渗透技术总结】SQL手工注入总结
数据库·sql
独行soc3 小时前
#渗透测试#漏洞挖掘#红蓝攻防#护网#sql注入介绍06-基于子查询的SQL注入(Subquery-Based SQL Injection)
数据库·sql·安全·web安全·漏洞挖掘·hw
独行soc5 小时前
#渗透测试#漏洞挖掘#红蓝攻防#护网#sql注入介绍08-基于时间延迟的SQL注入(Time-Based SQL Injection)
数据库·sql·安全·渗透测试·漏洞挖掘
White_Mountain5 小时前
在Ubuntu中配置mysql,并允许外部访问数据库
数据库·mysql·ubuntu
老王笔记5 小时前
GTID下复制问题和解决
mysql
清平乐的技术专栏6 小时前
Hive SQL 查询所有函数
hive·hadoop·sql
GISer_Jing6 小时前
2025前端面试热门题目——计算机网络篇
前端·计算机网络·面试
m0_748245526 小时前
吉利前端、AI面试
前端·面试·职场和发展