主键:
表中任何列都可以作为主键,但必须满足:- 任何两行不能有相同的主键
- 每一行都必须有主键,即主键值不能是null
- 主键的值不能修改
- 主键的值不能重用,即某行被删除了,他的主键值也不能再给其他行用。
select时,如果没有指定返回顺序,那么返回的结果是没有特定顺序的,可能是记录被加到表中的顺序,也可能不是。
使用order by 可以指定一个或多个列。按顺序优先级。
order by 必须是select的最后一条子句,否则出错。
order by支持按相对位置排序,即order by 2,3。
指定降序desc。注意desc只对前面的列名有效,如果要对多个列都降序,那么每个列后面都要加desc。sql语句是不区分大小写的。但是表名,列名和值得情况有所不同,要看具体的DBMS及其如何配置。
sql中的所用空格会被忽略。不能部分使用distinct。distinct关键字作用于select的所有列。
限制返回的数量。
这个有点麻烦了,因为各个数据库对这一sql实现各不相同。sql server 和access:
select top 5 name from students;
DB2
select name from students fetch first 5 rows only;
oracle
select name from students where rownum <= 5;
mysql,mariaDB,postgreSQL,SQLite
select name from students where limit 5;
对于limit再多说一句,
select name from students where limit 5 offset 5;
意思是从第5行之后,取5行记录。即返回第6,7,8,9,10行。
limit 指从哪开始,offset是取得行数。limit的含义不一样了。
我们要时刻意识到,各个sql实现的不同,不能想当然的认为sql是通用的。- 混用and 和 or 时,请使用括号。即使我们都知道and的优先级更高。
- in 操作符比一组or操作要快。
- 通配符只能用于搜索文本字段。通配符不会匹配null。
% 0个1个多个字符
_ 1个字符
[]指定字符集内的1个字符。只有access和sql server 支持。
注意,通配符搜索比较慢,不要放在select条件的前面,要放到靠后的位置。 拼接字段。
sql server,access 使用 +
oracle,sqlite使用 ||
mysql,mariadb使用Concat()语句去掉空格
trim()
rtrim()
ltrim()- 小技巧
select语句省略from子句,可用于方便的测试计算。如select 2 * 3;返回6
select now();返回当前时间。 - 聚集函数
avg(),avg函数忽略值为null的行。
count(),count(*)包含null值行,count(特定列)忽略null值行。distinct不能用于count(*)
max(),用于文本数据时,返回排序后的最后一行。
min(),忽略null
sum() - 分组数据 group by
- group by子句可以包含任意数目的列,因而可以对分组进行嵌套,更细致的进行数据分组。
- 如果group by 子句中嵌套了分组,数据将在最后指定的分组上进行汇总。换句话说,在建立分组时,指定的所有列都一起计算。
- group by 子句中列出的每一列都必须是检索列或者有效的表达式(不能是聚集函数)。如果select中使用的是表达式,那么group by也必须使用相同写法的表达式,不能用别名。
- select的列中,除了聚集函数以外,其他的列都必须在group by子句中给出。
- group by必须在where之后,order by 之前。就是说sql先根据where过滤,再分组,最后对结果排序。
过滤分组 having
where条件是对行进行过滤。
having子句是对分组进行过滤。实际上where可以用having代替,此时可以理解成每行都是一个组。
where子句是在分组前进行过滤,having是在分组后过滤。一前一后,可以联合起来使用。子查询
指的是条件中的查询。灵活,但不优雅。少用。组合查询 union
使用union,可以给出多条select语句,将他们的结果组合成一个结果集。
union的每个查询,必须包含相同的列,表达式或聚集函数,但是顺序不要求一致。
union默认的是取消重复行。
如果想包含重复,用union all。
union的组合查询语句中,只能在最后一个select上使用order by。- 一次插入多行,复制行
通常一次insert语句只能插入一行。
但是insert 和select连用时,不管select 返回多少行,都会被insert插入。这可用于复制行。
insert的列和select的列名字不需要相同,它关心的是位置,select出的第一列会被插到insert表的第一列。 复制表
select * into student2 from student1;
mysql,Oracle上的语法:
create table student2 as select * from student1;delete
- delete一个被外键关联的行,会报错。这很友好。
- 如果想要删除表中的所有行,可以使用truncate table语句,这个速度更快,因为不记录数据的变动。
视图
视图是虚拟的表。表是存储数据的。视图不存储数据,只包含使用时动态查询数据的select语句。- 性能问题。复杂的视图,嵌套视图,会严重影响性能。
- 视图必须唯一命名。
- 视图通常用于查询。对于视图的增删改限制很多。
存储过程
简单来说,存储过程就是为以后使用而保存的一条或多条sql语句。索引
为什么使用索引?原因就是:恰当的排序。
数据表的主键总是排序的,因此使用主键查询总是一种快速有效的操作。
但是搜索其他列通常效率不高。解决办法就是建索引。- 索引可以改善搜索的性能,但是降低了插入,修改和删除的性能。因为在做这些操作的时候,要动态更新索引。
- 索引要占大量的存储空间。
- 经常查的,并且值得量比较大的适合建索引。
- 索引可以建在多个列上。这个索引就只对这多个列排序,如果只是对其中某个列查询,这个索引是起不到任何加速效果的。
- 索引的效率随着表数据的增加或改变而变化。因此,虽好经常使用数据库提供的工具检查索引的效率。
触发器
触发器是一种特殊的存储过程。与某个表相关联。当这个表执行特性操作(增删改)时,触发触发器的执行。
约束比触发器要快,因此总是优先使用约束。
sql必知必会
最新推荐文章于 2024-07-30 09:39:28 发布