What is SQL?
Structured Query Language(结构化查询语言)
SQL是数据查询语言,数据库(Oracle、MySql、SQLite、Microsoft SQL Server)等是存储与管理数据的软件
关系型数据库(Relational databases)
数据库由若干张表(Table)组成,Table也是由行和列组成
一个Table存储一个类别的数据,每一行是一条数据,每一列是这种数据的一种属性
Table就像一个二维的表格,列是有限固定的,行(rows)是无限不固定的
SELECT 查询
SELECT语句,通常又称为查询(queries),SELECT可以用来从数据库中取出数据
取出表中所有数据的一个或某几个属性列
Select 查询某些属性列(specific columns)的语法
SELECT column(列名) , another column , ... FROM mytable(表名);
查询的结果是一个二维的表格,由行(rows)和列(columns)组成
取出所有列的数据
可以把所有列名写上,不过更简单的方式用星号 (
*
) 来代表所有列
SELECT * FROM mytable(表名) ;
条件查询
SELECT
查询的 WHERE
子句
SELECT column, another_column, …
FROM mytable
WHERE condition
AND/OR another_condition
AND/OR …;
数字类型属性筛选
虽然之前我们的SQL 关键字如 SELECT
, WHERE
, AND,OR
都是大写的,但SQL其实是兼容写成 select,where小写的
大写这些关键字有助于我们把 关键字 和 你的表名,列名区分开,让 SQL更容易理解。
字符串类型属性筛选
在字符串表达式中的字符串需要用引号 " 包含,如果不用引号,SQL会认为是一个属性列的名字
查询结果Filtering过滤 和 sorting排序
DISTINCT
关键字
指定某个或某些属性列唯一返回
选取出唯一的结果的语法
SELECT DISTINCT column, another_column, …
FROM mytable
WHERE condition(s);
因为
DISTINCT
语法会直接删除重复的行, 还有GROUP BY
语句,GROUP BY
也会返回唯一的行,不过可以对具有相同的 属性值的行做一些统计计算,比如:求和.
结果排序 (Ordering results)
结果排序(ordered results)
SELECT column, another_column, …
FROM mytable
WHERE condition(s)
ORDER BY column ASC/DESC;
ASC升序 或 DESC 降序
通过Limit选取部分结果
LIMIT
和OFFSET
子句通常和ORDER BY
语句一起使用,当我们对整个结果集排序之后,可以LIMIT
来指定只返回多少行结果 ,用OFFSET
来指定从哪一行开始返回。
limited查询
SELECT column, another_column, …
FROM mytable
WHERE condition(s)
ORDER BY column ASC/DESC
LIMIT num_limit OFFSET num_offset;
用JOINs进行多表联合查询
数据库范式(normalization)
数据库范式是数据表设计的规范,在范式规范下,数据库里每个表存储的重复数据降到最少(这有助于数据的一致性维护),同时在数据库范式下,表和表之间不再有很强的数据耦合,可以独立的增长
用JOINs进行多表联合查询
主键(primary key)
一般关系数据表中,都会有一个属性列设置为
主键(primary key)
。主键是唯一标识一条数据的,不会重复(想象你的身份证号码)。一个最常见的主键就是auto-incrementing integer(自增ID,每写入一行数据ID+1)当然字符串,hash值等只要是每条数据是唯一的也可以设为主键借助
主键(primary key)
(其他唯一性的属性也可以),我们可以把两个表中具有相同 主键ID的数据连接起来
INNER JOIN
用INNER JOIN 连接表的语法
SELECT column, another_table_column, …
FROM mytable (主表)
INNER JOIN another_table (要连接的表)
ON mytable.id = another_table.id
WHERE condition(s)
ORDER BY column, … ASC/DESC
LIMIT num_limit OFFSET num_offset;
外连接(OUTER JOINs)
LEFT JOIN,RIGHT JOIN 和 FULL JOIN
用LEFT/RIGHT/FULL JOINs 做多表查询
SELECT column, another_column, …
FROM mytable
INNER/LEFT/RIGHT/FULL JOIN another_table
ON mytable.id = another_table.matching_id
WHERE condition(s)
ORDER BY column, … ASC/DESC
LIMIT num_limit OFFSET num_offset;
在表A 连接 B,
LEFT JOIN
保留A的所有行,不管有没有能匹配上B 反过来RIGHT JOIN
则保留所有B里的行。最后FULL JOIN
不管有没有匹配上,同时保留A和B里的所有行将两个表数据1-1连接,保留A或B的原有行,如果某一行在另一个表不存在,会用 NULL来填充结果数据
在用这三个JOIN时,需要单独处理 NULL
特殊关键字 NULLs
outer-joining 多表连接,A和B有数据差异时,必须用
NULL
来填充。这种情况,可以用IS NULL
和IS NOT NULL
来选在某个字段是否等于NULL
.
在查询条件中处理 NULL
SELECT column, another_column, …
FROM mytable
WHERE column IS/IS NOT NULL
AND/OR another_condition
AND/OR …;
在查询中使用表达式
在SQL中可以用col_name(属性名)的地方,都可以用表达式 来指定对属性进行一定的计算或处理
SELECT particle_speed / 2.0 AS half_particle_speed (对结果做了一个除2)
FROM physics_data
WHERE ABS(particle_position) * 10.0 >500
(条件要求这个属性绝对值乘以10大于500);
每一种数据库(mysql,sqlserver等)都有自己的一套函数,包含常用的数字,字符串,时间等处理过程.具体需要参看相关文档
SQL提供了
AS
关键字, 来给表达式取一个别名
AS使用别名
SELECT col_expression AS expr_description, …
FROM mytable;
在查询中进行统计
对全部结果数据做统计
SELECT AGG_FUNC(column_or_expression) AS aggregate_description, …
FROM mytable
WHERE constraint_expression;
分组统计
GROUP BY
数据分组语法可以按某个col_name对数据进行分组,如:GROUP BY Year
指对数据按年份分组, 相同年份的分到一个组里。如果把统计函数和GROUP BY
结合,那统计结果就是对分组内的数据统计了
用分组的方式统计
SELECT AGG_FUNC(column_or_expression) AS aggregate_description, …
FROM mytable
WHERE constraint_expression
GROUP BY column;
HAVING语法
在
GROUP BY
分组语法中,我们知道数据库是先对数据做WHERE
,然后对结果做分组,如果我们要对分组完的数据再筛选出几条如何办?一个不常用的语法
HAVING
语法将用来解决这个问题,它可以对分组之后的数据再做SELECT筛选
用HAVING进行筛选
SELECT group_by_column, AGG_FUNC(column_expression) AS aggregate_result_alias, …
FROM mytable
WHERE condition
GROUP BY column
HAVING group_condition;
查询执行顺序
这才是完整的SELECT查询
SELECT DISTINCT column, AGG_FUNC(column_or_expression), …
FROM mytable
JOIN another_table
ON mytable.column = another_table.column
WHERE constraint_expression
GROUP BY column
HAVING constraint_expression
ORDER BY column ASC/DESC
LIMIT count OFFSET COUNT;
FROM
和 JOIN
s
FROM
或 JOIN
会第一个执行,确定一个整体的数据范围. 如果要JOIN不同表,可能会生成一个临时Table来用于 下面的过程。总之第一步可以简单理解为确定一个数据源表(含临时表)
WHERE
我们确定了数据来源 WHERE
语句就将在这个数据源中按要求进行数据筛选,并丢弃不符合要求的数据行,所有的筛选col属性 只能来自FROM
圈定的表. AS别名还不能在这个阶段使用,因为可能别名是一个还没执行的表达式
GROUP BY
如果你用了 GROUP BY
分组,那GROUP BY
将对之前的数据进行分组,统计等,并将是结果集缩小为分组数.这意味着 其他的数据在分组后丢弃.
HAVING
如果你用了 GROUP BY
分组, HAVING
会在分组完成后对结果集再次筛选。AS别名也不能在这个阶段使用.
SELECT
确定结果之后,SELECT
用来对结果col简单筛选或计算,决定输出什么数据.
DISTINCT
如果数据行有重复DISTINCT
将负责排重.
SELECT Title, (SELECT MAX(Domestic_sales+International_sales)
FROM Boxoffice) - SUM(Domestic_sales+International_sales)
AS Diff FROM Movies INNER JOIN Boxoffice
ON Movies.ID = Boxoffice.Movie_id
GROUP BY Title;