由于之前在学校使用的SQL语句都是简单的增删改查,但简单的增删改查很难完成工作需求,同时也要兼顾性能需求,所以因为工作需求,特意买了《SQL学习指南》加深对SQL的理解与掌握。本文并非简单的介绍SQL的增删改查,但也不会涉及到太多SQL的背后实现原理。如果简单的增删改查无法满足你的日常使用,相信本文会对你的SQL学习带来帮助。
-
用户输入的查询语句会传递给查询优化器,优化器会为查询找到最有效率的执行方式
-
null值
- 没有合适的值
- 值未确定
- 值未定义
当使用不熟悉的数据库时,首先确定哪些列可以允许null值,在过滤的时候才去适当的措施确保不会漏掉所需要的数据。
select * from tb where id != 6 or id is NULL
-
使用distinct关键字去除重复项
select distinct id from tb where id > 10;
-
使用group by 子句请求数据库服务器对数据进行分组
select id, count(*) from tb group by id;
查询以id为分组条件,将id相同的行放入同一组并统计得到id相同的数量
由于group by 子句在where子句被评估之后运行,所以分组无法在where子句中增加过滤条 件,必须在having子句中使用分组过滤条件
/*筛选相同id超过四个*/ select id from tb group by id having count(*) > 4;
-
多列分组:分别对多列进行组合
/*id和name的各种组合,即id和name的笛卡尔积*/ select * from tb group by id, name;
-
由于分组的group by子句是在where子句评估之后运行,所以要仔细查询的过滤条件是针对分组之前的原始数据(过滤条件放在where子句中),还是针对分组后的数据(过滤条件放在having子句中)
-
子查询:包含在另一个SQL语句内部的查询。任何子查询返回的数据在包含语句执行完成后都会被丢弃,子查询类似于一个具有作用域的临时表。
select * from tb where id = (select id from tb_join);
-
非关联子查询:子查询可以单独执行而不需要引用包含语句中的任何内容。(例如上面的例子,子查询可以作为一个单独的SQL语句执行,在包含语句执行之前一次执行完毕)
-
关联子查询:子查询依附于包含语句并引用其一列或多列。关联子查询不是在包含语句执行之前一次执行完毕,而是作为每一个候选行执行一次
/*子查询的执行必须依赖包含查询提供的tb.id,先从tb表中检索出所有的记录,接着为每行记录执行一次子查询,每次执行包含查询都要向子查询传递id*/ select * from tb where tb.name = (select name from tb_join where tb.id = tb_join.tb_id);
-
有时通过单表查询可能无法满足我们的需求,就需要通过多表查询实现。
- 内连接:如果连接的两张表的条件,一张表满足条件,另一张不满足,结果集中将会排除包含该条件的行
- 外连接:不考虑每行是否在另一个表中存在匹配,结果集会包含第一个表中的所有行,但仅仅包含第二个表中哪些匹配行的数据
- 左外连接:left outer join。关键词left指出连接左边的表决定结果集的行数,而右边的只负责提供与之匹配的列值。与此相反的右外连接的right指右边的表决定行数。
-
两张表以上的连接:前两个表的连接作为一个结果集,之后的表与之前的结果集连接,随着表的不断连接,包含了越来越多的列。(通俗来讲就是前两张表连接得到“中间结果集”,“中间结果集”和后面紧跟着的表再进行连接得到新的“中间结果集”,一直到最后一张表。类似于滚雪球)
-
索引:用于定位表中行的列,描述这些行的物理位置的信息,并不包含实体中的所有数据。索引的作用就是便捷化检索表中行和列的子集,这样每次查询就不需要遍历表中的所有行。
/*创建索引*/ alter table tb add index tb_idx (name);
当表被创建时,MySQL会自动为主键列生成索引。
唯一索引:除了有常规索引的作用,还可以限制索引列出现重复值。服务器会为主键检查唯一性。
-
每个索引事实上是一个表(一种特殊类型的表),所以索引越多,服务器就需要做更多的工作来保持所有模式对象最新。所以创建索引要综合考虑:
- 所有主键列被索引
- 所有被外键约束引用的列创建索引
- 被频繁检索的列创建索引
-
约束:一种简单地强加于表中一列或多列的限制。(主键约束、外键约束、唯一约束、检查约束)
网友评论