加入收藏 | 设为首页 | 会员中心 | 我要投稿 源码门户网 (https://www.92codes.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MySql教程 > 正文

10个简单步骤,完全理解SQL

发布时间:2019-06-04 11:21:52 所属栏目:MySql教程 来源:IT技术圈
导读:副标题#e# 多年前收藏在笔记中的一篇文章,今天偶然翻出,重读了一遍,依然大有收获。分享出来,大家一起探讨。 以本文是为了以下读者而特地编写的: 1、 在工作中会用到 SQL 但是对它并不完全了解的人。 2、 能够熟练使用 SQL 但是并不了解其语法逻辑的人

尽管没有严格的规定说明你何时应该使用 IN ,何时应该使用 EXISTS ,但是这些事情你还是应该知道的:

  • IN比 EXISTS 的可读性更好
  • EXISTS 比IN 的表达性更好(更适合复杂的语句)

二者之间性能没有差异(但对于某些数据库来说性能差异会非常大) 因为使用 INNER JOIN 也能得到书名表中书所对应的作者信息,所以很多初学者机会认为可以通过 DISTINCT 进行去重,然后将 SEMI JOIN 语句写成这样:

  1. -- Find only those authors who also have books 
  2. SELECT DISTINCT first_name, last_name 
  3. FROM author 
  4. JOIN book ON author.id = book.author_id 

这是一种很糟糕的写法,原因如下:

  • SQL 语句性能低下:因为去重操作( DISTINCT )需要数据库重复从硬盘中读取数据到内存中。
  • 这么写并非完全正确:尽管也许现在这么写不会出现问题,但是随着 SQL 语句变得越来越复杂,你想要去重得到正确的结果就变得十分困难。

ANTI JOIN

这种连接的关系跟 SEMI JOIN 刚好相反。在 IN 或者 EXISTS 前加一个 NOT 关键字就能使用这种连接。举个例子来说,我们列出书名表里没有书的作者:

  1. -- Using IN 
  2. FROM author 
  3. WHERE author.id NOT IN(SELECT book.author_id FROM book) 
  4.   
  5. -- Using EXISTS 
  6. FROM author 
  7. WHERE NOT EXISTS (SELECT 1 FROM book WHEREbook.author_id = author.id) 

关于性能、可读性、表达性等特性也完全可以参考 SEMI JOIN。

CROSS JOIN

这个连接过程就是两个连接的表的乘积:即将第一张表的每一条数据分别对应第二张表的每条数据。我们之前见过,这就是逗号在 FROM 语句中的用法。在实际的应用中,很少有地方能用到 CROSS JOIN,但是一旦用上了,你就可以用这样的 SQL语句表达:

  1. -- Combine every author with every bookauthor CROSS JOIN book 

DIVISION DIVISION 的确是一个怪胎。简而言之,如果 JOIN 是一个乘法运算,那么 DIVISION 就是 JOIN 的逆过程。DIVISION 的关系很难用 SQL 表达出来,介于这是一个新手指南,解释 DIVISION 已经超出了我们的目的。

我们学到了什么?

学到了很多!让我们在脑海中再回想一下。 SQL 是对表的引用, JOIN 则是一种引用表的复杂方式。但是 SQL 语言的表达方式和实际我们所需要的逻辑关系之间是有区别的,并非所有的逻辑关系都能找到对应的 JOIN 操作,所以这就要我们在平时多积累和学习关系逻辑,这样你就能在以后编写 SQL 语句中选择适当的 JOIN 操作了。

7、 SQL 中如同变量的派生表

在这之前,我们学习到过 SQL 是一种声明性的语言,并且 SQL 语句中不能包含变量。但是你能写出类似于变量的语句,这些就叫做派生表:

说白了,所谓的派生表就是在括号之中的子查询:

  1. -- A derived table 
  2. FROM(SELECT * FROM author) 

需要注意的是有些时候我们可以给派生表定义一个相关名(即我们所说的别名)。

  1. -- A derived table with an alias 
  2. FROM(SELECT * FROM author) a 

派生表可以有效的避免由于 SQL 逻辑而产生的问题。

举例来说:如果你想重用一个用 SELECT 和 WHERE 语句查询出的结果,这样写就可以(以 Oracle 为例):

  1. -- Get authors' first and last names, and their age in days 
  2. SELECT first_name, last_name, age 
  3. FROM( 
  4.  SELECT first_name, last_name, current_date- date_of_birth age 
  5.  FROM author 
  6. -- If the age is greater than 10000 days 
  7. WHEREage > 10000 

需要我们注意的是:在有些数据库,以及 SQL : 1990 标准中,派生表被归为下一级——通用表语句( common table experssion)。这就允许你在一个 SELECT 语句中对派生表多次重用。

上面的例子就(几乎)等价于下面的语句:

  1. WITH a AS( 
  2.  SELECT first_name, last_name, current_date- date_of_birth age 
  3.  FROM author 
  4. SELECT * 
  5. FROM a 
  6. WHERE age > 10000 

当然了,你也可以给“ a ”创建一个单独的视图,这样你就可以在更广泛的范围内重用这个派生表了。

我们学到了什么?

我们反复强调,大体上来说 SQL 语句就是对表的引用,而并非对字段的引用。要好好利用这一点,不要害怕使用派生表或者其他更复杂的语句。

8、 SQL 语句中 GROUP BY 是对表的引用进行的操作

让我们再回想一下之前的 FROM 语句:

  1. FROM a, b 

现在,我们将 GROUP BY 应用到上面的语句中:

  1. GROUP BY A.x, A.y, B.z 

(编辑:源码门户网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!