本笔记整理自《SQL 基础教程》《MySQL 必知必会》和网上资料。个人笔记不保证正确。

一、复杂查询

视图

将 SELECT 查询包装成一个虚拟表,该虚拟表就被称为视图。(因为只是一个包装,因此视图的数据也会随着原表的更新而更新)

  1. 用途:

    1. 简化复杂的SQL查询,用它替换子查询,能降低查询的嵌套深度。
    2. SELECT 查询的重用,减少重复查询。
    3. ...
  2. 创建视图:
CREATE VIEW <视图名称>
(<视图列名1>, <视图列名2>... )
AS
<SELECT 语句>;

其中 SELECT 的结果列和视图列名一一对应。

3. 视图的限制

1. 视图的 SELECT 子句,不能包含 ORDER BY 子句。因为视图也是表,而表是集合,它没有顺序。(也有些DB支持该用法,但不通用)

1. 视图的更新:只在很有限的条件下,才能在视图上使用 INSERT/DELETE/UPDATE 这样的变更数据的语句。(视图应该只用于检索,能不更新就不要更新它

4. 删除视图:DROP VIEW <视图名称>;

子查询

子查询,其实就是一次性的视图:

SELECT ...
FROM (
SELECT ... -- 这就是一个子查询:嵌套的 select 语句
) AS <别名>
...

上面的查询的 FROM 子句中,给另一 SELECT 子句定义了一个别名,并将它作为了查询对象。这就是一个子查询。

子查询不仅能用于 FROM,还能用在 WHERE 子句等很多地方。

关联子查询

即用到了外部数据的子查询语句:

SELECT ...
FROM product AS p1
WHERE (
SELECT ...
FROM duck AS p2
WHERE p1.price > p2.price -- 这里,内部子查询访问了外部查询的表p1,因此是一个关联子查询。
);

二、函数、谓词、CASE 表达式

函数

给出的链接都是 MySQL 的

  1. 算术函数

    • 加减乘除:+ - * /
    • ABS 绝对值
    • MOD 求余
    • ROUND 四舍五入
  2. 字符串函数
    • CONCAT(str1,str2,...) 拼接
    • LENGTH(str) 字符串的 bytes 长度
    • CHAR_LENGTH(str)
    • LOWER/UPPER 大小写转换
    • REPLACE(str,from_str,to_str) 替换
    • SUBSTRING(str FROM pos FOR len) 截取
  3. 时间和日期函数
    • CURRENT_DATE 当前日期
    • CURRENT_TIME 当前时间
    • CURRENT_TIMESTAMP 当前的日期和时间
    • EXTRACT(unit FROM date) 截取日期元素,unit 可为 YEAR MONTH HOUR 等等
  4. 转换函数
    • CAST(expr AS type) 将 expr 的结果转换成 type 类型
    • COALESCE(value,...) 从左往右扫描,返回第一个非 NULL 的值。常用于将 NULL 转换为其他值。eg. COALESCE(sth, 1) 如果 sth 为 NULL 就会返回1.
  5. 聚合函数:基本就五个,已经学过了。

谓词

即返回布尔值的表达式

LIKE谓词——简单字符串匹配(慢)

匹配整个列

  • %:任意字符出现任意次
  • _:匹配任意一个字符

举例:

SELECT name
FROM list
WHERE name LIKE '%Ryan%'; -- 匹配任意包含 'Ryan' 的字符串

REGEXP谓词——正则字符串匹配

MySQL 只实现了通用正则的一个子集,而且是search模式。(非match)

其他

  • BETWEEN:范围匹配,eg. BETWEEN 1 AND 10
  • IS NULL、IS NOT NULL
  • IN、NOT IN:是否在某集合内
  • EXIST、NOT EXIST(比较难的一个,入门阶段不要求):该谓词比较特殊,只需要右侧一个参数,而且该参数绝大多数情况下,都是一个关联子查询。而且该子查询的SELECT子句的参数基本可以随意,通常使用SELECT *. 对于子查询有返回值的列,它返回True,否则返回False. 但要注意为 NULL 时返回 UNKNOW.(而 WHERE 只认 True)

CASE 表达式

  1. if - else if - else 形式:
CASE WHEN <求值表达式> THEN <表达式>
WHEN <求值表达式> THEN <表达式>
WHEN <求值表达式> THEN <表达式>
... ELSE <表达式>
END
  1. switch 模式(但不需要break)
CASE <表达式>
WHEN <表达式> THEN <表达式>
WHEN <表达式> THEN <表达式>
... ELSE <表达式>
END

这是对 CASE 后的元素做switch比较。

三、集合运算

注意事项

  1. 作为运算对象的结果集,列字段必须一一对应,而且对应列的类型必须相同。

结果集的交并差

  1. <查询1> UNION <查询2>:对两个结果集求并
  2. UNION ALL:添加 ALL 能使结果集包含重复行。
  3. <查询1> INTERSECT <查询2>:两结果集的交集
  4. <查询1> EXCEPT <查询2>:两结果集的差集

以列为单位,对表进行联结(JOIN)

最强大的功能之一

交并差是以行为单位的操作,是竖向的运算。而联结是以列为单位的操作,是横向的拼接。

内联(INNER JOIN)

内联结果只包含两表的交集

语法:

SELECT ...
FROM (product INNER JOIN shop
ON product.p_id = shop.p_id)
WHERE filter_condition;

使用 跟在 INNER JOIN 子句后的 ON 子句指定联结条件。(这里我特意用了括号,表示 JOIN 和 ON 两个子句是配套的)

也有另一个很常用的语法(但是现在已经不推荐使用):

SELECT ...
FROM product, shop
WHERE product.p_id = shop.p_id
AND filter_condition;

对于 shop 表中有多行对应同一个 product 的情况(有多人购买了同一款商品),结果中该 product 会被复制给 shop 中的多个购买记录。(也就是说该 product 会变成多行)

INNER 可以省略,也就是说只写 JOIN,就默认是 INNER JOIN

外联(OUTER JOIN)

外联以某表为主表,将另一表的列联结到该表。另一表没有值的列,就用 NULL 代替。使用LEFTRIGHT指定主表。(两个关键字都能实现同样的效果,不过用 LEFT 的多一些)

语法:

SELECT ...
FROM product LEFT OUTER JOIN shop
ON product.p_id = shop.p_id;

这和内联很相似,差别只是联结关键词改成了LEFT OUTER JOIN。这表示以左边的表为主表,把右边的表的内容联结上去。因此左表的所有列都会出现在结果集中。

多表联查举例:

-- 登录异常的账号及密码
select distinct batches.identity_number as '登录失败账号', accounts.password
from ((batches left outer join tasks
on batches.id = tasks.batch_id) -- 批次表联结具体的任务表
left outer join `status`
on tasks.id = status.task_id) -- 再联结上状态表
left outer join accounts
on batches.identity_number = accounts.identity_number -- 再联结上账号表
where `status`.step_type = 'check_login' -- 只提取 "check_login" 步骤的记录
and status.status != 'info' -- 状态不为 info,说明登录异常

此外还有 FULL OUTER JOIN 表示返回左右两表的所有行!所有没有匹配的行都给出 NULL

P.S. 其中的关键字 OUTER 通常可省略。但是 LEFT、RIGHT、FULL 不可以省略。

画外:字段引用符号

如果数据库的字段名/数据库名/表名可能和数据库关键字重复,就需要用引用符号将他们引用起来,消除歧义。

MySQL 中经常用反引号干这个事。

而 SQL Server 则使用方括号。

标准 SQL 使用双引号。在看到这些符号时要知道这些差别。

完。(接下来就是用 Python/Java 连接 MySQL 了)

SQL 基础笔记(二):进阶查询的更多相关文章

  1. JavaScript基础笔记二

    一.函数返回值1.什么是函数返回值    函数的执行结果2. 可以没有return // 没有return或者return后面为空则会返回undefined3.一个函数应该只返回一种类型的值 二.可变 ...

  2. [SQL基础教程] 3-4 对查询结果进行排序/ORDER BY

    [SQL基础教程] 3-4 对查询结果进行排序/ORDER BY ORDER BY SELECT <列名1>,<列名2>,<列名2>... FROM ORDER B ...

  3. SQL 基础笔记(一)

    本笔记整理自<SQL 基础教程>.<MySQL 必知必会>和网上资料.个人笔记不保证正确. 一.基础 SQL,即结构化查询语言,是为访问与操作关系数据库中的数据而设计的语言. ...

  4. Oracle数据库之SQL基础(二)

    一.约束 ❤ 1.约束概述 约束作用: (1)定义规则 (2)确保完整性:包括数据的精确性.可靠性.以确保数据不会出错,或者尽量减少出错. 约束的类型: (1)非空约束 (2)主键约束 (3)外键约束 ...

  5. sql基础笔记备忘

    MySQL中定义数据字段的类型对你数据库的优化是非常重要的. MySQL支持多种类型,大致可以分为三类:数值.日期/时间和字符串(字符)类型. 数值类型:tinyint smallint medium ...

  6. 《SQL Server 2012 T-SQL基础》读书笔记 - 7.进阶查询

    Chapter 7 Beyond the Fundamentals of Querying window function是什么呢?就是你SELECT出来一个结果集,然后对于每一行,你都想给它对应一个 ...

  7. SQL基础笔记

    Codecademy中Learn SQL, SQL: Table Transformaton和SQL: Analyzing Business Metrics三门课程的笔记,以及补充的附加笔记. Cod ...

  8. SQL基础(二):SQL命令

    1.SQL SELECT TOP 子句 SELECT TOP 子句用于规定要返回的记录的数目.SELECT TOP 子句对于拥有数千条记录的大型表来说,是非常有用的(或者比如选取某个最新的数据:我们可 ...

  9. SQL学习笔记二之MySQL的数据库操作

    阅读目录 一 系统数据库 二 创建数据库 三 数据库相关操作 一 系统数据库 information_schema: 虚拟库,不占用磁盘空间,存储的是数据库启动后的一些参数,如用户表信息.列信息.权限 ...

随机推荐

  1. BCB::TClientSocket,TServerSocket控件

    一,首先服务端开启监听 ServerSocket1->Port=StrToInt(5000); ServerSocket1->Active=true; ServerSocket1控件,响应 ...

  2. pyinstaller打包后的exe退出时,类中的__del__不执行问题

    关于pyinstaller打包后的exe退出时,类中的__del__不执行问题,完善中

  3. C#流程控制语句

    C#流程控制语句 一.选择语句 当程序中需要进行两个或两个以上的选择时,可以根据条件的判断来选择将要执行的一组语句. ?if语句 ?switch语句 二.循环语句 循环语句是对一个程序模块进行的重复操 ...

  4. C#接口定义

    C#接口定义 C#不支持多重继承,但是客观世界出现多重继承的情况又比较多.为了避免传统的多重继承给程序带来的复杂性等问题,C# 提出了接口的概念.通过接口可以实现多重继承的功能.  继承该接口的类或结 ...

  5. java基础1.5版后新特性 自动装箱拆箱 Date SimpleDateFormat Calendar.getInstance()获得一个日历对象 抽象不要生成对象 get set add System.arrayCopy()用于集合等的扩容

    8种基本数据类型的8种包装类 byte Byte short Short int Integer long Long float Float double Double char Character ...

  6. centos6 下查看SELinux状态 关闭SELinux

    转载自:https://blog.csdn.net/boomjane_testingblog/article/details/52859977 SELinux(Security-Enhanced Li ...

  7. Thymeleaf显示Map集合数据

    <select class="form-control zz-set-input-size" id="channel"> <option va ...

  8. java的八种基本数据类型

             据说表格的方式一目了然 一. java数据类型的取值范围如下: 注意:long型后如果不加 L 则默认为int型,float型如果不加 F 则默认为double型: 注意!注意!注意 ...

  9. 标签种类及CSS引入方法

    标签种类及CSS引入方法 标签种类: 一:块级标签(block) ——> 独占一行,默认宽度与内容无关,宽高可设   (hr 块级标签) 二:行内块标签(inline-block) ——> ...

  10. Python全栈day 03

    Python全栈day 03 一.运算符补充 in ,逻辑运算符,判断某字符或某字符串是否在一个大的字符串中,输出得到bool型数据. value = '我是中国人' v = '我' if v in ...