SQL语法基础
什么是 SQL?
DML和DDL
可以把 SQL 分为两个部分:数据操作语言 (DML)
和 数据定义语言(DDL)
。
SQL 的数据操作语言(DML)用于更新、插入和删除记录的语法。
- SELECT - 从数据库表中获取数据
- UPDATE - 更新数据库表中的数据
- DELETE - 从数据库表中删除数据
- INSERT INTO - 向数据库表中插入数据
SQL 的数据定义语言 (DDL) 部分使我们有能力创建或删除表格。我们也可以定义索引(键),规定表之间的链接,以及施加表间的约束。
- CREATE DATABASE - 创建新数据库
- ALTER DATABASE - 修改数据库
- CREATE TABLE - 创建新表
- ALTER TABLE - 变更(改变)数据库表
- DROP TABLE - 删除表
- CREATE INDEX - 创建索引(搜索键)
- DROP INDEX - 删除索引
基础语法
DISTINCT
SELECT DISTINCT Company FROM Orders —— 从Company列选取唯一不同的值(指定列去重查询)
WHERE
SELECT * FROM Persons WHERE (City='Beijing' or City='Xian') AND age BETWEEN 0 AND 10 —— Where用于指定查询条件(BETWEEN:在某个范围内)
ORDER BY
SELECT Company, OrderNumber FROM Orders ORDER BY Company DESC, OrderNumber ASC —— ORDER BY用于根据指定字段排序字段排序,DESC:降序,ASC:升序
INSERT INTO
INSERT INTO 表名称 VALUES (值1, 值2,....)
INSERT INTO Persons VALUES ('Gates', 'Bill', 'Xuanwumen 10', 'Beijing') —— 指定表插入一行数据
INSERT INTO table_name (列1, 列2,...) VALUES (值1, 值2,....),(值1, 值2,....)....
INSERT INTO Persons (LastName, Address) VALUES ('Wilson', 'Champs-Elysees'),('leo', 'xi-an') —— 指定表插入指定列数据
UPDATE
UPDATE 表名称 SET 列名称 = 新值 WHERE 列名称 = 某值
UPDATE Person SET Address = 'Zhongshan 23', City = 'Nanjing' WHERE LastName = 'Wilson' —— 修改表数据
DELETE
DELETE FROM 表名称 WHERE 列名称 = 值
DELETE FROM Person WHERE LastName = 'Wilson' —— 删除表数据
DELETE FROM table_name —— 可以在不删除表的情况下删除所有的行,表的结构、属性和索引都是完整的
TOP、LIMIT
规定返回记录的数目在不同数据库的用法
SQL Server 语法 SELECT TOP 2 * FROM Persons SELECT TOP 50 PERCENT * FROM Persons MySQL 语法 SELECT column_name(s) FROM table_name LIMIT number SELECT *FROM Persons LIMIT 5 Oracle 语法<br> SELECT column_name(s) FROM table_name WHERE ROWNUM <= number SELECT * FROM Persons WHERE ROWNUM <= 5
LIKE
- 常用符号
通配符 | 描述 |
---|---|
% | 包含零个或更多字符的任意字符串。 |
_ | 任何单个字符。 |
[ ] | 指定范围 ([a-f]) 或集合 ([abcdef]) 中的任何单个字符。 |
[^] | 不属于指定范围 ([a-f]) 或集合 ([abcdef]) 的任何单个字符。 |
-
实例参考
SELECT * FROM Persons WHERE City LIKE 'Ne%' —— 查询Ne开头的数据 SELECT * FROM Persons WHERE City LIKE '%lond%' —— 查询包含lond开头的数据 SELECT * FROM Persons WHERE FirstName LIKE '_eorge' —— 查询第一个字符之后是eorge的数据 SELECT * FROM Persons WHERE City LIKE '[ALN]%' —— 以 "A" 或 "L" 或 "N" 开头的数据 SELECT * FROM Persons WHERE City LIKE '[!ALN]%' —— 不以 "A" 或 "L" 或 "N" 开头的数据 -
通配符匹配实例
符号 | 含义 |
---|---|
LIKE '5[%]' | 5% |
LIKE '[_]n' | _n |
LIKE '[a-cdf]' | a、b、c、d 或 f |
LIKE '[-acdf]' | -、a、c、d 或 f |
LIKE '[ [ ]' | [ |
LIKE ']' | ] |
LIKE 'abc[_]d%' | abc_d 和 abc_de |
LIKE 'abc[def]' | abcd、abce 和 abcf |
IN
IN 操作符允许我们在 WHERE 子句中规定多个值。
SELECT column_name(s) FROM table_name WHERE column_name IN (value1,value2,...)
SELECT * FROM Persons WHERE LastName IN ('Adams','Carter')
BETWEEN
选取介于两个值之间的数据范围,这些值可以是数值、文本或者日期。
SELECT column_name(s) FROM table_name WHERE column_name BETWEEN value1 AND value2
SELECT * FROM Persons WHERE LastName BETWEEN 'Adams' AND 'Carter' SELECT * FROM Persons WHERE LastName NOT BETWEEN 'Adams' AND 'Carter'
不同的数据库对 BETWEEN...AND 操作符的处理方式是有差异的。某些数据库会列出介于 "Adams" 和 "Carter" 之间的人,但不包括 "Adams" 和 "Carter" ;某些数据库会列出介于 "Adams" 和 "Carter" 之间并包括 "Adams" 和 "Carter" 的人;而另一些数据库会列出介于 "Adams" 和 "Carter" 之间的人,包括 "Adams" ,但不包括 "Carter" 。
AS
用于给表或者列起别名.
SELECT City as c FROM Persons as p WHERE p.LastName BETWEEN 'Adams' AND 'Carter'
JOIN
INNER JOIN
取两个表的交集,主要用于多个不同的表取出满足公共条件的数据
select table1.name,table2.address from table1 INNER join table1.id=table2.id
select table1.name,table2.address from table1,table2 where table1.id=table2.id
以上两行sql执行结果一样,但是当两张表的数据量较大时,又需要连接查询时,应该使用inner join的语法,因为后者会在内存中先生成一张数据量比较大的笛卡尔积表,增加的内存的开销
LEFT JOIN
从左表返回所有的行,如果有某行未满足连接条件依然会返回,只是说右表相应的字段是null。
左连接查询语句:
select t1.Customer,t1.City,t2.country From customers as t1 LEFT JOIN cities as t2 on t1.City=t2.city_name;
查询的结果表:
另外在左连接查询中,单表查询的很多语法都是同样适用,如:
SELECT t1.Customer, t1.City, t2.country FROM customers as t1 LEFT JOIN cities as t2 ON t1.City = t2.city_name WHERE t1.Items_purchased= 'pencil' and t1.Amount_paid > 50; SELECT t1.Items_purchased, count(t2.country) FROM customers as t1 LEFT JOIN cities as t2 ON t1.City = t2.city_name GROUP BY t1.Items_purchased;
RIGHT JOIN
右连接参考左连接,并且两者是可以转换的。
FULL JOIN
全连接可以看成左连接和右连接的并集。
select t1.Customer,t1.City,t2.country From customers as t1 FULL JOIN cities as t2 on t1.City=t2.city_name;
同样是上边的表我们使用全链接查询后的结果如下:
CROSS JOIN
SELF JOIN
UNION
用于合并两个或者多个SELECT语句的结果集,每个SELECT语句必须有相同数量的列,并且列必须是相似的数据类型,列的顺序也必须相同。
默认取不重复的值
SELECT column_name(s) FROM table_name1 UNION SELECT column_name(s) FROM table_name2
加上ALL取所有值
SELECT column_name(s) FROM table_name1 UNION ALL SELECT column_name(s) FROM table_name2
INTO
一般select into和 insert into都是用来复制表,两者的主要区别为: select into要求目标表不存在,因为在插入时会自动创建。insert into select要求目标表存在。
SELECT INTO
SELECT value1, value2 into Table2 from Table1
INSERT INTO
Insert into Table2(field1,field2,...) select value1,value2,... from Table1
由于Table2是已存在的表,所有除了可以插入Table1的字段外,还可以插入常量,如:
Insert into Table2(a,b,c) select value1,value2,6 from Table1
CASE WHEN
- 简单case函数
case sex
when '1' then '男'
when '2' then '女’
else '其他' end
- case搜索函数
case when sex = '1' then '男'
when sex = '2' then '女'
else '其他' end
示例:
SELECT case WHEN t1.category_type='error1' THEN t2.name||'错误1' WHEN t1.category_type='error2' THEN (CASE t1.col_key WHEN '123' THEN '位置1' WHEN '456' THEN '位置2' ELSE NULL END||'错误2') ELSE NULL END as error FROM first_table t1 INNER JOIN sec_table t2 ON t1.id = t2.id WHERE t1.id=233 AND error NOTNULL
表创建相关
创建数据库
CREATE DATABASE database_name
创建表
CREATE TABLE 表名称
(
列名称1 数据类型,
列名称2 数据类型,
列名称3 数据类型,
....
)
约束
-
非空约束(not null)、唯一性约束(unique)、主键约束(primary key) PK、外键约束(foreign key) FK使用说明参考如下链接:
使用说明 -
CHECK 约束
CHECK 约束用于限制列中的值的范围,如果对单个列定义 CHECK 约束,那么该列只允许特定的值,如果对一个表定义 CHECK 约束,那么此约束会在特定的列中对值进行限制。
创建表时添加约束:
CREATE TABLE Persons ( Id_P int NOT NULL, LastName varchar(255) NOT NULL, FirstName varchar(255), Address varchar(255), City varchar(255), CONSTRAINT chk_Person CHECK (Id_P>0 AND City='Sandnes') )
已存在表添加约束:
ALTER TABLE Persons ADD CONSTRAINT chk_Person CHECK (Id_P>0 AND City='Sandnes')
撤销约束:
ALTER TABLE Persons
DROP CONSTRAINT chk_Person
- DEFAULT 约束
DEFAULT 约束用于向列中插入默认值。
创建表时添加约束:
CREATE TABLE Orders ( Id_O int NOT NULL, OrderNo int NOT NULL, OrderName DEFAULT 'moti-c' Id_P int, OrderDate date DEFAULT GETDATE() ) MySQL: ALTER TABLE Persons ALTER City SET DEFAULT 'SANDNES' SQL Server / Oracle / MS Access: ALTER TABLE Persons ALTER COLUMN City SET DEFAULT 'SANDNES'
删除约束:
MySQL: ALTER TABLE Persons ALTER City DROP DEFAULT SQL Server / Oracle / MS Access: ALTER TABLE Persons ALTER COLUMN City DROP DEFAULT
索引
在不读取整个表的情况下,索引可以加快查询,但是更新一个包含索引的表比更新一个没有索引的表耗费的时间更多,这是由于索引本身也需要更新。因此,理想的做法是仅仅在常常被搜索的列(以及表)上面创建索引。
CREATE INDEX index_name ON table_name (column_name) ——创建简单索引
CREATE UNIQUE INDEX index_name ON table_name (column_name) ——创建唯一索引
CREATE INDEX PersonIndex ON Person (LastName DESC) ——创建降序索引
CREATE INDEX PersonIndex ON Person (LastName, FirstName) ——创建多行索引
Drop、Alter、INCREMENT
Drop
-
删除索引:
MS Access: DROP INDEX index_name ON table_name SQL Server: DROP INDEX table_name.index_name DB2/Oracle: DROP INDEX index_name MySQL: ALTER TABLE table_name DROP INDEX index_name -
删除数据库:
DROP DATABASE database_name -
删除表:
DROP TABLE table_name TRUNCATE TABLE table_name;(仅删除表内数据,不删除表本身)
Alter
-
向表中添加列:
ALTER TABLE table_name ADD column_name data_type -
删除表中的列:
ALTER TABLE table_name DROP COLUMN column_name -
修改表中列的数据类型
SQL Server / MS Access ALTER TABLE table_name ALTER COLUMN column_name data_type MySQL / Oracle ALTER TABLE table_name MODIFY COLUMN column_name data_type Oracle 10G 之后版本: ALTER TABLE table_name MODIFY column_name data_type; -
Sql仅支持重命名表和向已有的表中添加列:
ALTER TABLE [database_name.]table_name RENAME TO new_table_name; ALTER TABLE table_name ADD columnName column_definition, ADD columnName column_definition
INCREMENT
-
SqlLite:
CREATE TABLE tbl_employee ( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, name CHAR(64) NOT NULL, age INTEGER NOT NULL, city CHAR(64), salary REAL ); -
MySql:
CREATE TABLE IF NOT EXISTS tbl_employee( id INT UNSIGNED AUTO_INCREMENT, name CHAR(64) NOT NULL, age INTEGER NOT NULL, city CHAR(64), PRIMARY KEY (id) )ENGINE=InnoDB auto_increment=1000 DEFAULT CHARSET=utf8mb4; ALTER TABLE tbl_language AUTO_INCREMENT = 100 —— 创建之后赋初值 -
Access:
CREATE TABLE Persons ( P_Id int PRIMARY KEY AUTOINCREMENT, LastName varchar(255) NOT NULL, FirstName varchar(255), Address varchar(255), City varchar(255) ) -
SqlServer
CREATE TABLE Persons ( P_Id int PRIMARY KEY IDENTITY, LastName varchar(255) NOT NULL, FirstName varchar(255), Address varchar(255), City varchar(255) )
数据类型
SQL函数
简单函数
column指的列名
函数 | 含义 | 用法 |
---|---|---|
avg(column) | 返回某列的平均值(NULL值不包括在计算中) | SELECT AVG(column_name) FROM table_name |
count(column) | 返回某列的行数(不包括NULL值) | SELECT COUNT(column_name) FROM table_name |
count(*) | 返回查询到的行数 | SELECT COUNT(*) FROM table_name |
COUNT(DISTINCT column) | 返回相异结果的数目 | SELECT COUNT(DISTINCT column_name) FROM table_name |
first() | 返回在指定查询中第一个记录的值 | SELECT FIRST(column_name) FROM table_name |
last() | 返回在指定查询中最后一个记录的值 | SELECT LAST(column_name) FROM table_name |
max(column) | 指定列的最高值 | SELECT MAX(column_name) FROM table_name |
min(column) | 指定列的最低值 | SELECT MIN(column_name) FROM table_name |
sum(column) | 返回某列的总和(可能返回null) | SELECT SUM(column_name) FROM table_name |
ucase() | 把字段的值转换为大写。 | SELECT UCASE(column_name) FROM table_name |
icase() | 把字段的值转换为小写。 | SELECT LCASE(column_name) FROM table_name |
mid() | 用于从文本字段中提取字符 | SELECT MID(column_name,startPos,length) FROM table_name SELECT MID(City,1,3) as SmallCity FROM Persons |
len() | 返回文本字段中值的长度。 | SELECT LEN(column_name) FROM table_name |
round() | 把数值字段舍入为指定的小数位数。 | SELECT ROUND(column_name,decimals) FROM table_name SELECT ProductName, ROUND(UnitPrice,2) as UnitPrice FROM Products —— unitPrice保留两位小数 |
now() | 返回当前的系统日期 | SELECT NOW() FROM table_name |
Having、Format及日期函数
SQL 中的 HAVING 子句用于筛选分组 ( GROUP BY ) 后的各组数据,相当于 SELECT 语句中的 WHERE 语句,HAVING 子句一般跟在 GROUP BY 子句后面。
SELECT column_name, aggregate_function(column_name) FROM table_name WHERE column_name operator value GROUP BY column_name HAVING aggregate_function(column_name) operator value;
SELECT lession_name, SUM(views) as total_views FROM lession_views GROUP BY lession_name HAVING total_views < 100;
运算符
- 算术运算符
运算符 | 示例 | 示例 |
---|---|---|
+ |
两个操作数相加 | A + B = 15 |
- |
从第一个减去第二个操作数 | A - B = 5 |
* |
将两个操作数相乘 | A * B = 50 |
/ |
从第一个除以第二个操作数 | A / B = 2 |
** |
指数运算符,提出一个操作数到其他的幂值 | A ** B = 100000 |
- 逻辑运算符
运算符 | 示例 | 示例 |
---|---|---|
= |
检查两个操作数的值是否相等,如果是,则条件成立。 | (A = B)为假 |
!= ,<> ,~= |
检查两个操作数的值是否相等,如果两个值不相等则条件成为真。 | (A != B)为真 |
> |
检查左操作数的值是否大于右操作数的值,如果是,则条件成为真。 | (A > B) 为假 |
< |
检查左操作数的值是否小于右操作数的值,如果是,则条件成为真。 | (A < B) 条件为真。 |
>= |
检查左操作数的值是否大于或等于右操作数的值,如果是,则条件成为真。 | (A >= B) 为假 |
<= |
检查左操作数的值是否小于或等于右操作数的值,如果是,则条件成为真。 | (A <= B) 为真 |
- 其他运算符
运算符 | 操作描述 |
---|---|
ΙΙ | 连接不同列的值形成新的值 |
NOT |
逻辑否定 |
AND |
连词(逻辑与) |
OR |
包含(逻辑或) |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!