关系型数据库的威力在于它能将两种东西关联起来,即能把多个表中查询出来的数据结合在一起解答单个数据表不足以解答的问题。
联结查询(join)
把多张表查询到的同类数据进行匹配得到的查询结果。
子查询
多表操作的另一种方法是将SELECT 语句嵌套到另一个SELECT 语句中,称之为子查询。
以下用实例分别说明。
给定日期查询分数。
首先在grave_event表中找到特定日期的行
,
得到对应行号的event_id和score的event_id进行匹配。输出对应列。
FROM,要检索的表。
ON,两张表的联结条件,表里的值必须匹配。
注意使用(表名.列名)的语法。最好是在使用联结查询时候,每个列名之前都要附带表名。
然后上面的SQL变成了下面的形式:
简洁明了!
三张表查询:
内联结搭配统计:
内联结原理。
SELECT
COUNT(*)
FROM
`hi_wtgl_wtjl` AS a
最后得到166 条数据。
SELECT
COUNT(*)
FROM
`hi_wtgl_wtxx` AS a
147个数据。
SELECT
COUNT(*)
FROM
`hi_wtgl_wtxx` AS a,
`hi_wtgl_wtjl` AS b
居然查处24402条数据。166*147=24402。
换联结查询试试。
SELECT
COUNT(*)
FROM
`hi_wtgl_wtxx` AS a
JOIN `hi_wtgl_wtjl` AS b
结果相同。在查询时间方面,这两条语句也是相同的。
当执行
SELECT
COUNT(*)
FROM
`hi_wtgl_wtxx` AS a,
`hi_wtgl_wtjl` AS b,
`hi_wtgl_fjxx` AS c
之后,结果有14W条。现在你知道那个垃圾系统一条SQL查询300多亿条数据是怎么来的了吧。
现在揣测以下sql语句操作步骤,首先执行的是FROM后面的语句,看有多少张表,假设有这么一个容器(每次查询新建一张表),当只有一张表的时候,新表直接指向旧表,然后做WHERE后面的操作(过滤满足条件的数据,把不满足条件的数据剔除)。最终在所有满足条件的表中执行SELECT 后面的数据。并返回。(多表联结查询实质就是拼接所有行,每一表中的行都要对应另外一张表的所有数据。)链接表越多,数据扩大倍数越大,内链接查询,所有表都可看作是主表的一部分。里面的每张表都同等重要。
假如每张表重要程度不一样,看看下面的
左查询(LEFT JOIN)
使用左查询的时候,必须加入限定条件 on假如像以下这样的话
SELECT
COUNT(*)
FROM
`hi_wtgl_wtxx` AS a
LEFT JOIN `hi_wtgl_wtjl` AS b
会报错!
SELECT
COUNT(*)
FROM
`hi_wtgl_wtxx` AS a
LEFT JOIN `hi_wtgl_wtjl` AS b
ON a.`wtid` = b.`wtid`
以上语句输出 221
反过来的话
SELECT
COUNT(*)
FROM
`hi_wtgl_wtjl` AS a
LEFT JOIN `hi_wtgl_wtxx` AS b
ON a.`wtid` = b.`wtid`
输出166 .
从这看,使用左联结比使用子联结效率不知道高了多少!
假设一下左查询的实现原理。首先获得左查询 FROM后面的表为‘主表‘,读取ON 后面的检索条件,整队主表中的每条数据,都执行一次查询语句,然后把满足条件的副表中的数据和主表进行整合成一条新数据。
最后返回。
从这个原理看,似乎这些跨表查询的效率的差不多。。。只是最后显示的东西有区别。显示的少,执行的步骤多,显示的多,执行的步骤少。
多表LEFT JOIN
一个表是另一个表的左查询。原理应该同两表查询。猜想下步骤,首先获得主表,然后通过主表获得副表,再通过副表获得副副表。最后整合成一张大表。
子查询
第一个SELECT 的查询结果作为第二个查询语句的条件。
子查询不仅仅能用 IN 或者 NOT IN。
子查询:
是错误的。
才正确。
高级一点的子查询。
IN 、NOT IN
对应一列数据去情况。
多列查询情况:
ALL,ANY,SOME的子查询
只有一条满足条件, ALL 集合里面所有日期都要和要查询的birth做比较,有一条不满足都要舍去。
ANY 意义就不大了。
有一条满足就行。
EXISTS ,NOT EXISTS
这个值返回 true 或者False
UNION 进行多数据检索:
用于合并两个或多个 SELECT 语句的结果集,并消去表中任何重复行。使用第一个SELECT作为结果集字段。所有有效信息存放在第一个SELECT的字段中。这里的重复数据是指结果集中所有数据都相同。
而UNION ALL 进行数据检索的时候,会合并所有数据而不进行消除重复行。
注意: UNION 的结果集列的名字来源于第一个SELECT语句中列的名字,后面跟着的SELECT必须有相同数目的列,但有关列不必有相同的名字和数据类型。
一图看懂: