SQL 语法
约 1675 个字 85 行代码 预计阅读时间 7 分钟
SQL虽然有统一的标准,但是各家公司产品的语法并不完全统一,部分是因为不同的数据库公司要体现自己产品的特点。SQL语句可以分为DDL,DML和DCL三类。这篇文章里面是mysql
和sql server
语法都有,具体会有说明。
语法及分类
通用规则
- 单行或者多行书写,以分号结尾
- MySQL的语句不区分大小写,关键字建议使用大写
- 注释:
- 单行注释:
--
或者#
(MySQL特有) - 多行注释:
/* */
DDL
创建库
新建一个数据库,但是如果有图形化界面(如SSMS)可能就无需这么做
创建表
新建一张表
比如我新建一张图书的表
CREATE TABLE book(
bno char(8) PRIMARY KEY,
category char(10),
title varchar(40) not null,
press varchar(30),
year int,
author varchar(20),
price decimal(7,2),
total int,
stock int
-- 主键也可以写在最后
-- PRIMARY KEY(bno)
CHECK (stock >= 0)
);
常见的类型有:
char(n)
:固定长度为n的字符串,输入数据可以长度不足,虽然会浪费空间,但是如果超长应该会被阻止输入varchar(n):
最长为n的字符串,会根据字符串实际长度调整存储空间大小int
:整型,也许还会有smallint
float(n)
:浮点型,至少有n位小数numeric(m,n)
:m位精度,n位小数date
:日期,在sql sever
里面是datetime
,格式为2025-02-26
time
:时间,格式为13:14:15
SQL 提供了用于类型转换计算的函数,但是这个不是很统一,列举一些基本都有的:
Abs
:绝对值exp
:指数round
:四舍五入sin
cos
删除和修改
首先是删除表,一般来说可能会需要管理员权限
其次可以给表增加列,新增的列默认值是null
也可以删除列,这个很多数据库都不支持
此外还可以调整
创建索引
索引会优化查询速度,如果你要经常用某个键查询,那么最好给这个键创建一个索引
选择
查询语句
SQL 里面最复杂的就是查询,有非常多相关的语法和技巧。
基础用法
用于从数据库中选取数据,可以指定多个字段,不指定则会选择所有字段
或者,其中*是通配符,表示选择表中的所有列
有个冷知识,SELECT 1
并非毫无意义,它常用于测试数据库连接;还有另一个冷知识,SQL不允许在名称中有-
,此外SQL中的名称是大小写不敏感的,一般关键字大写,其余小写。
SQL是允许表中有重复(没有设置主键或者UNIQUE之类的)和查询结果有重复的,我们可以使用DISTINCT
来去重,与之相对的关键字是ALL
,默认状态下就是ALL
SQL查询是允许进行计算的,比如
重命名
可以用AS
来给重命名,既可以是属性名,也可以是表名。
WHERER 子句
condition 可以使用AND
、 OR
和NOT
以及BETWEEN
连缀
需要注意SQL里面的不等于是<>
以及WHERE
子句里面是不允许有聚合函数的,这是因为 WHERE
子句用于在聚合之前过滤行,而聚合函数是对一组行进行计算。
ORDER BY 关键字
用于对结果集按照一个列或者多个列进行排序
SELECT column1, column2, ... FROM table_name
ORDER BY column1, column2, ... DESC; --默认是升序,但是经常需要的是降序
ASC是升序,DESC是降序
SELECT LIMIT 子句
用于只需要查询前几行数据的情况,mysql
是LIMIT
但sql server
是TOP
number2
条记录开始截取number1
条记录
LIKE 操作符
用于模糊化查询,类似于正则表达式
pattern中可以使用通配符: *%
用于匹配任意字符串
* _
用于匹配单个字符
* []
用于匹配字符列中的任何单一字符
* [^]
用于匹配不在字符列中的任何单一字符
字符串操作
比如我想在查询结果前面加一串文字,在mysql
里面是CONCAT
以及转换大小写,求字符串长度等操作都有相应函数
BETWEEN 操作符
用于选取介于两个值之间的数据范围内的值
聚合查询
对于统计总数、平均数这类计算,SQL提供了专门的聚合函数,包括以下这些 |函数|说明| |-|-| |COUNT|计算行数| |AVG|计算平均值| |SUM|计算最大值| |MAX|计算某一列的最大值| |MIN|计算某一列的最小值|
SQL还提供了分组聚合的功能,可以用GROUP BY
进行分组。需要注意在有聚合函数的情况下,不是聚合函数的属性必须在GROUP BY
列表里面,换言之就是SELECT
子句中的列必须是聚合函数或 GROUP BY
子句中包含的列
HAVING 子句
对聚合函数结果进行选择,需要注意,HAVING
子句里面的元素如果不是聚合函数里的属性,那么就必须在GROUP BY
列表里面
关于 null
null
表示未定义,不等于0,含null
的算数运算结果都是null
,含null
的逻辑比较结果都是unknow
,对unknow
的逻辑运算比较特别,既不能肯定它也不能否定它
此外需要注意null
是不能用=null
去判定的,正确的写法应该是is null
聚合函数除了COUNT
都会忽略null
,如果全是null
,结果也自然是null
嵌套查询
也可以叫子查询(subquery),查询的结果是一张表,然后我们对这张表进行查询,格式是(SELECT 语句);
SELECT DISTINCT course_id FROM section
WHERE semester = 'Fall' and yaer = 2025
and course_id in (
SELECT course_id FROM section
WHERE semester = 'Spring'
and year = 2024
);
子查询操作
some
与集合中的某些值比较,相当于存在
=some
和in
是等价的,但是反过来不等价,!=some
不等价于not in
ALL
与集合中任意元素比较,相当于任意,可以用来查找最大或者最小的元素
空集测试
用于判断子查询是否存在,EXIST r
等价于r
非空
唯一性
unique
用于验证子查询结果中是否有重复语句
视图
用于对特定的用户隐藏特定的数据,主要是出于安全考虑
复合查询
导出关系
相当于从子查询结果中查询,这种情况下必须给子查询结果命名
SELECT dept_name, avg_salary
FROM (
SELECT dept_name, avg(salary)
FROM instructors
GROUP BY dept_name
) AS dept_avg(dept_name, avg_salary) --相当于一个视图
WHERE avg_salry > 42000;
WITH 语句
允许创建局部(针对一个查询语句而言)视图,而非全局,上面那个查询语句可以改写为
WITH dept_avg(dept_name, avg_salary) AS
SELECT dept_name, avg(salary)
FROM instructors
GROUP BY dept_name
SELECT dept_name, avg_salary
FROM dept_avg
WHERE avg_salry > 42000;
修改与删除
INSERT INTO 语句
用于向表中插入新记录,没有指定要插入数据的列名的形式需要列出插入行的每一列名称:
也可以指定列名和插入的值UPDATE 语句
用于更新指定值
DELETE 语句
用于删除表中的行