SQL
SQL是关系数据库的查询语言.在SQL中最难的应该算是查询。本篇文章, 注重点在于总结基础的sql语句, 重点讲述查询语句。
下面提供了可以练习sql的数据库, 直接导入数据库运行即可.
- company.sql
- world.sql
管理数据库的SQL
连接登入
mysql -u用户名 -hIP地址 -p密码 -P端口号
假设我要连接到本地的Mysql服务器, 其端口号是3306
, 用户名是root
, 密码是123456
。则应该写成入下语句
mysql -uroot -p123456 -h127.0.0.1 -P3306
修改密码
登入数据库中, 我们有时候会有修改密码的需求.
set password for
用户名@
主机名= password(密码)
- 密码使用单引号括起来.
- 用户名、主机名使用飘号括起来.
查看服务器中所有数据库
show databases;
切换数据库
切换到world数据库
use world;
查看数据库中的所有表
show tables;
丢库
drop database world;
这种语句很少会用, 危险指数太高
丢表
drop table customer;
操作表的SQL
清空表中记录
delete from customer;
注意: 一般delete from我们会配合where来匹配要删除的记录.如果不写,默认就是全部删除.相当于WHERE 1=1
查看表中的记录
select
字段名列表
from
表名 别名
WHERE 过滤条件
- 过滤条件为true才显示出来.不写的话, 相当于
WHERE 1 = 1
例如查看customer表
,该表只有一条记录,执行如下sqlselect * from customer;
添加(插入数据)到表
INSERT INTO 表名
(
字段名1,
字段名2,
字段名N
) VALUES (
值1,
值2,
值N
)
为了和Oracle的添加语句兼容, 最好是一次插入一条.因为Oracle不支持mysql的批量添加数据的语法。
创建表
建表的语法和添加格式很像, 比较大的区别是其字段名后要说明数据类型。而且也没有VALUES后的子句。
create table tableName (
字段名1 数据类型1,
字段名2 数据类型2
);
更新数据
update 表名
SET 字段名1 = 值1,
字段名2 = 值2
WHERE 过滤条件;
联接查询
假设我们又如下两张表,一张城市表, 一张国家表.表结构如下
现在有一个需求, 需要我们查出每个国家首都的名字.在国家表中的Captial字段存的是城市表中城市的ID.这时候我们就需要用到联接查询.而SQL最早的时候给我们提供了两表联接的语法,又叫做逗号
笛卡尔积和逗号
笛卡尔积是一种数学预算
在数学中,两个集合X和Y的笛卡儿积(Cartesian product),又称直积,在集合论中表示为X × Y,是所有可能的有序对组成的集合,其中有序对的第一个对象是X的成员,第二个对象是Y的成员。
之所以要介绍笛卡尔积的定义是因为做表联接的逗号本质上就是做笛卡尔积,更具笛卡尔积的定义, 即组合两个集合所有的有序对的运算.对于两张表A、B来说, 笛卡尔积运算就是, 依次取A中的记录和B中的记录组合, 这样就能得到所有的有序对, 因为我们首先保证了A的顺序,然后又保证了B的顺序, 不会出现重复的对。
需求
现在有一个需求, 需要我们查出每个国家首都的名字.在国家表中的Captial字段存的是城市表中城市的ID
讲了那么多在看下面的sql代码应该能够理解,由于逗号
联接本质是做笛卡尔积,结果太大.所以一般我们会加条件
语句进行过滤
。
SELECT co.`Name` '国家', ci.`Name` '首都'
FROM
Country co, City ci
WHERE co.Capital = ci.ID
-- 这句sql意思局势拿表Coutry和City做联接(笛卡尔积),并做等值条件判断,取出满足条件的集合
内联接
为什么有内联接
内联接的概念其实就是逗号联接, 本质就是做笛卡尔积运算.但是由于教早的SQL语句, 没有把联接语句
和普通条件过滤语句(WHERE)
区分开来, 导致写的sql并不是那么容易阅读, 因为我们看到WHERE字句的时候,还要判断 这是在做普通的条件过滤,还是在做联接
.于是就有内连接语法,专门为了链接而诞生。
语法
select *
from
A
inner join
B
on 条件
如上述语法,我们可以将上述需求的sql写成内联接语法。如下
SELECT
co.`Name` '国家',
ci.`Name` '首都'
FROM
Country co
inner join
City ci
on
co.Capital = ci.ID
外联接
- 外联接存在的问题是,如果数据中匹配的字段.如有的
Country的Capital
字段值为NULL(不是'null'字符串).NULL参与的预算结果都为false
, 则会导致有的国家信息被丢弃。 - 但是现实中, 我们遇到业务需求很可能是要打印出表中国家的首都, 就算没有这个国家首都的数据,我们也要打印出这个国家.
外联接就是用来解决上述提到的问题,外联接可以保存指定一边的表格数据.外联接又分为 左联接
和右联接
,但是往往我们习惯用 左联接
,因为对于 右联接
我们只需要把表格对调也能实现.
左联接
保存左表联接表的数据
语法
select
字段列表(逗号分隔)
from
表A
left [outer] join
表B
on
条件
--- outer可以省略不写
需求
现在有一个需求, 需要我们查出每个国家首都的名字.在国家表中的Captial字段存的是城市表中城市的ID.对于Capital字段为NULL的首都也要保留其数据
SELECT
co.`Name` '国家',
ci.`Name` '首都'
FROM
Country co
left outer join
City ci
on
co.Capital = ci.ID
如下图,左外联接, 计算国家的首都字段为NULL为输出.一共是239条记录,比内联接多了7条
右联接
将左联接的A、B表对调即为右联接.
SQL字句的运算顺序
虚表
所谓的虚表,就是实际在数据库并不存在的表.但是其表示形式和数据库的实际表一样.
如下sql语句 select * from Country;
查询出的结果表即称为虚表
顺序
先FROM加载对应的基表--> WHERE字句过滤数据-->SELECT 确定字段 --> 生成虚表 --> ORDER BY排序
其他
给表取别名
- 位置: 我们可以给表取别名, 在
FROM语句后
. - 注意:
一旦给表取别名, 真名就不能用
.因为FROM字句是最新加载的, 所以我们给表取别名后, sql语句中的真表名就不能用了,但数据库中的表名没变。
给字段取别名
- 位置:
在SELECT 语句
select name as '国家' from Country
select name '国家' from Country
两句等效,表示给name取别名,叫国家.
- 注意: SELECT字句是在FROM和WHERE字句后加载,
所以其别名不能用在上述两个字句中
.SELECT字句加载后虚表也就确定了数据.所以ORDER BY是可以使用 字段别名
WHERE等价于ON
where等价于on,但是一般不这样写.on一般只配合join才规范