基本介绍
- DML(data manipulation language): 它们是SELECT、UPDATE、INSERT、DELETE,就象它的名字一样,这4条命令是用来对数据库里的数据进行操作的语言 。
- DDL(data definition language): DDL比DML要多,主要的命令有CREATE、ALTER、DROP等,DDL主要是用在定义或改变表(TABLE)的结构,数据类型,表之间的链接和约束等初始化工作上,他们大多在建立表时使用 。
- DCL(Data Control Language): 是数据库控制功能。是用来设置或更改数据库用户或角色权限的语句,包括(grant,deny,revoke等)语句。在默认状态下,只有sysadmin, dbcreator,db_owner 或者 db_securityadmin 等人员才有权力执行DCL。
模式定义了数据如何存储、存储什么样的数据以及数据如何分解等信息,数据库和表都有模式。
主键的值不允许修改,也不允许复用(不能使用已经删除的主键值赋给新数据行的主键)。
# 注释
SELECT *
FROM mytable; -- 注释
/* 注释1
注释2 */
数据库创建与使用:
CREATE DATABASE test;
USE test;
创建表
CREATE TABLE mytable (
id INT NOT NULL AUTO_INCREMENT,
col1 INT NOT NULL DEFAULT 1,
col2 VARCHAR(45) NULL,
col3 DATE NULL,
PRIMARY KEY (`id`));
修改表
添加列
ALTER TABLE mytable ADD col CHAR(20);
删除列(需要DROP 删除需要制定行、列、表格名)
ALTER TABLE mytable DROP COLUMN col;
删除表
DROP TABLE mytable;
插入
普通插入(列名存在,但是数据原先不存在)
INSERT INTO mytable col1,col2 VALUES(val1,val2);
插入搜索出来的数据。(将mytable2中的col3和col4中的内容,插入到表mytable1中的col1和col2列中)
INSERT INTO mytable1 col1,col2 SELECT col3,col4 FROM mytable2
将表mytable中的列col1和col2,数据检索出来,组成一个新表(表名为newTable)
CREATE TABLE newTable AS SELECT col1,col2 FROM mytable;
更新表
主要是将原来有值的列数据更新为新的值,将表mytable中,id值为1的,列col所有值更新为val。
UPDATE mytable SET col = val WHERE id=1;
删除
-- 删除表结构
DROP table mytable;
TRUNCATE table mytable;
多种条件
查询条件
- 去除重复行 DISTINCT
- 获得指定范围 n 到 m (n < m)内容的行数,只有一个参数表示前n行。 limit n,m
- 查询出来的行按照指定顺序进行排序 ORDER BY col1 DESC, col2 ASC
其它过滤条件
操作符 | 说明 |
---|---|
= | 等于 |
< | 小于 |
> | 大于 |
<> != | 不等于 |
<= !> | 小于等于 |
>= !< | 大于等于 |
BETWEEN | 在两个值之间 |
IS NULL 为 NULL | 值 |
基本和Java没有什么区别,主要是有个 BETWEEN。也可以使用 AND 和 OR 两个关键词来连接
- IN 操作符,类似从指定的结果中枚举。
-- 从 Persons 的表格中,取出LastName列为 Adams 和 Carter 的人
SELECT * FROM Persons
WHERE LastName IN ('Adams','Carter')
- NOT 操作符,就是否操作。
通配符 LIKE
就类似与正则表达式
- % 表示任意的多个符号
- _ 表示一个符号
- [] 表示限定范围内的符号
-- 不以 A 和 B 开头的任意文本
SELECT *FROM mytable
WHERE col LIKE '[^AB]%';
多种内置的函数
-- CONCAT 进行字符串的拼接, TRIM 表示取出行的字符串
SELECT CONCAT(TRIM(col1), '(', TRIM(col2), ')') AS concat_col
FROM mytable;
还有一些专门用于文本处理的函数
分组 Group By
就是把具有相同值的数据值放到同一组之中。
-- 把 mytable 中具有相同名字的信息进行分组
SELECT name FROM mytable GROUP BY name;
-- 统计下相同名称的个数,并按照个数进行升序排序
SELECT name,count(*) as num FROM mytable GROUP BY name ORDER BY num;
WHERE 过滤行,HAVING 过滤分组,行过滤应当先于分组过滤。
-- 取出id为 4-10 的数据进行分组
SELECT name FROM mytable WHERE id BETWEEN 4 AND 10;
-- 进行 having 操作,取出分组后个数小于3的列
SELECT name,count(*) as num FROM mytable WHERE id BETWEEN 4 AND 10 group by name ORDER BY name having num <= 3;
分组规定:
- GROUP BY 子句出现在 WHERE 子句之后,ORDER BY 子句之前;
- 除了汇总字段外,SELECT 语句中的每一字段都必须在 GROUP BY 子句中给出;
- NULL 的行会单独分为一组;
- 大多数 SQL 实现不支持 GROUP BY 列具有可变长度的数据类型。
子查询
子查询中只能返回一个字段的数据。
-- 利用子查询找出 A 表中那些,在 A 表和 B 表中相同的字段
-- 子查询作为过滤条件
SELECT col1 FROM table_A WHERE col1 IN (SELECT col1 FROM table_B);
下面的语句可以检索出客户的订单数量,子查询语句会对第一个查询检索出的每个客户执行一次:
SELECT cust_name, (SELECT COUNT(*) FROM Orders
WHERE Orders.cust_id = Customers.cust_id) AS orders_num
FROM Customers ORDER BY cust_name;
连接-内连接、外连接
连接用于将多张表连接到一起,使用 JOIN 来,条件中使用 ON 而不是 WHERE。
内连接(等值连接)
SELECT A.value,B.value # 连接后的值
FROM tablea AS A INNER JOIN tableb AS B # tablea 和 tableb 进行内连接
ON A.key=B.key; # 内连接的等值条件
-- 将上面的内连接改为WHERE的等值方法
SELECT A.value,B.value
FROM tablea AS A,tableb AS B
WHERE A.key=B.key;
自连接
自连接可以看成内连接的一种,只是连接的表是自身而已。
-- 一张员工表,包含『员工姓名』和『员工所属部门』,要找出与 Jim 处在同一部门的所有员工姓名。
SELECT e1.name
FROM employee AS e1 INNER JOIN employee AS e2
ON e1.department = e2.department
AND e2.name = "Jim";
-- 非自连接版本
SELECT name FROM employee WHERE department = (SELECT department FROM employee WHERE name="Jim");
自然连接
表示将不同表格中,列名相同的数据自动的连接起来,同名列可以有多个。
和内连接的区别是,内连接是连接指定的连接条件,而自然连接是自动连接相同列名的列。
SELECT A.value,B.value FROM tablea AS A NATURAL JOIN tableb AS B;
外连接
外连接保留了没有关联的那些行。分为左外连接,右外连接以及全外连接,左外连接就是保留左表没有关联的行。
customers 表:
cust_id | cust_name |
---|---|
1 | a |
2 | b |
3 | c |
orders 表:
order_id | cust_id |
---|---|
1 | 1 |
2 | 1 |
3 | 3 |
4 | 3 |
预期执行结果:
cust_id | cust_name | order_id |
---|---|---|
1 | a | 1 |
1 | a | 2 |
3 | c | 3 |
3 | c | 4 |
2 | b | Null |
SELECT customers.cust_id,customers.cust_name,orders.order_id FROM customers LEFT JOIN orders On customers.cust_id=orders.cust_id;
组合查询
使用 UNION 来组合两个查询,如果第一个查询返回 M 行,第二个查询返回 N 行,那么组合查询的结果一般为 M+N 行。
每个查询必须包含相同的列、表达式和聚集函数。
默认会去除相同行,如果需要保留相同行,使用 UNION ALL。
只能包含一个 ORDER BY 子句,并且必须位于语句的最后。
SELECT col FROM mytable WHERE col = 1
UNION
SELECT col FROM mytable WHERE col =2;
视图
视图是虚拟的表,本身不包含数据,也就不能对其进行索引操作。
对视图的操作和对普通表的操作一样。
视图具有如下好处:
- 简化复杂的 SQL 操作,比如复杂的连接;
- 只使用实际表的一部分数据;
- 通过只给用户访问视图的权限,保证数据的安全性;
- 更改数据格式和表示。
CREATE VIEW myview AS
SELECT Concat(col1, col2) AS concat_col, col3*col4 AS compute_col
FROM mytable
WHERE col5 = val;
其它
还有很多高级的应用,这里不说了,给出参考链接
实际的一个应用场景 CMS 管理系统
CMS(Student Manager System)学生管理系统(数据库),里面包含了
学生基本信息(INFO): 学号 idno、姓名 name、年龄 age
学生成绩信息(CLASS_INFO): 学号 idno、 课程编号 class_id、 课程名称 class_name、 课程成绩 class_score
1 创建数据库,并使用
CREATE DATABASE mybase;
USE mybase
2 创建数据库表
CREATE TABLE mytable(
id INT(10) NOT NULL AUTO_INCREMENT;
col1 INT(10) NOT NULL default 1;
col2 VARCHAR(12) NOT NULL; # 注释: 创建不允许为空的字符串表名
-- ... 省略其它属性
PRIMARY KEY(`id`); # 设置主键,主键是 ` 符号,而不是' 号
);
3. 修改数据表- 删除行、列、表
-- 增加名称为 col1 的列
ALTER TABLE mytable ADD col1 VARCHAR(12);
-- 删除名称为 col1 的列
ALTER TABLE mytable DROP COLUMN col1;
4. 插入表结构、修改已插入的表结构
-- 插入具体的到表格中
INSERT INTO mytable(id,name) VALUES(12,"zhangsan");
-- 从其它的表格中选取数据插入到表格
INSERT INTO mytable(id,name) SELECT col1,col2 FROM othertable;
-- 更新已经存在表格属性,例如,将 id 为 12 的改为"lisi"
UPDATE mytable SET name="lisi" WHERE id=12;
SQL truncate 、delete与drop区别
相同点
- 都是执行删除操作
- truncate 和 drop 都是 DDL 语言,执行后会自动提交,而 delete 不会
不同点
- truncate 和 delete 都是只删除数据不删除表结构
- drop 语句将删除表的结构被依赖的约束(constrain)、触发器(trigger)、索引(index);依赖于该表的存储过程/函数将保留,但是变为 invalid 状态。
- 安全性:小心使用 drop 和 truncate,尤其没有备份的时候.否则哭都来不及
- 想删除部分数据行用 delete,注意带上where子句. 回滚段要足够大.
- 想删除表,当然用 drop
- 想保留表而将所有数据删除,如果和事务无关,用truncate即可。如果和事务有关,或者想触发trigger,还是用delete。
- 如果是整理表内部的碎片,可以用truncate跟上reuse stroage,再重新导入/插入数据。
5. 删除表格
-- 删除表格mytable 中 id 为 13 的行
DELETE FROM mytable WHERE id=13
-- TRUNCATE TABLE 可以清空表,也就是删除所有行。
TRUNCATE TABLE mytable;
6、查询表结构、去除相同值、指定范围、升序(降序)
-- 查询 mytable表中非相同的值
SELECT DISTINT col1,col2 FROM mytable;
-- 取查询结果的前5条
SELECT * FROM mytable WHERE ... LIMIT 5;
-- 去查询结果的 5-15条
SELECT * FROM mytable WHERE ... LIMIT 5,10;
-- 可以按多个列进行排序,并且为每个列指定不同的排序方式:
SELECT * FROM mytable ORDER BY col1 DESC,col2 ASC;
注意:
LIMIT m,n : 表示从第m+1条开始,取n条数据;
LIMIT n : 表示从第0条开始,取n条数据,是limit(0,n)的缩写。