连接查询补充

6.3.3 连接查询补充
建立连接查询可以通过SELECT语句的FROM子句或WHERE子句实现,但通过FROM子句实现有助于将连接操作与制定查询条件的WHERE子句区分开来,所以,在TRANSACT-SQL中推荐使用这种方法。
FROM子句一般格式
    FROM <TABLE_SOURCE> <JOIN_TYPE> <TABLE_SOURCE> ON <JOIN_CONDITION>
    | <TABLE_SOURCE> CROSS JOIN <TABLE_SOURCE>
 
一、交叉连接(CROSS JOIN)
    交叉连接(CROSS JOIN):有两种,显式的和隐式的,不带ON子句,返回的是两表的乘积,也叫笛卡尔积。
例如,在STORES书店表中共6家书店,DISCOUNTS折扣表针对书店的3种折扣,使用交叉连接查询语句所检索到的纪录数为6*3行。
执行语句
SELECT S.STOR_ID,S.STOR_NAME,D.STOR_ID,D.DISCOUNT
FROM STORES AS S
CROSS JOIN DISCOUNTS AS D


二、内连接(INNER JOIN)
内连接(INNER JOIN):有两种,显式的和隐式的,返回连接表中符合连接条件和查询条件的数据行。
例如:下面的语句3和语句4的结果是相同的。
语句3:隐式的内连接,没有INNER JOIN,形成的中间表为两个表的笛卡尔积。
SELECT O.ID,O.ORDER_NUMBER,C.ID,C.NAME FROM CUSTOMERS C,ORDERS O WHERE C.ID=O.CUSTOMER_ID;

语句4:显示的内连接,一般称为内连接,有INNER JOIN,形成的中间表为两个表经过ON条件过滤后的笛卡尔积。
SELECT O.ID,O.ORDER_NUMBER,C.ID,C.NAME FROM CUSTOMERS C INNER JOIN ORDERS O ON C.ID=O.CUSTOMER_ID;

三、外连接(OUTER JOIN):外连不但返回符合连接和查询条件的数据行,还返回不符合条件的一些行。
外连接分三类:左外连接(LEFT OUTER JOIN)、右外连接(RIGHT OUTER JOIN)和全外连接(FULL OUTER JOIN)。
三者的共同点是都返回符合连接条件和查询条件的数据行。
不同点如下:
左外连接还返回左表中不符合连接条件单符合查询条件的数据行。
右外连接还返回右表中不符合连接条件单符合查询条件的数据行。
全外连接还返回左表中不符合连接条件单符合查询条件的数据行,并且还返回右表中不符合连接条件单符合查询条件的数据行。全外连接实际是上左外连接和右外连接的数学合集(去掉重复),即“全外=左外 UNION 右外”。
说明:左表就是在“(LEFT OUTER JOIN)”关键字左边的表。右表当然就是右边的了。在三种类型的外连接中,OUTER 关键字是可省略的。

四、联合连接(UNION JOIN):这是一种很少见的连接方式。Oracle、MySQL均不支持,其作用是:找出全外连接和内连接之间差异的所有行。这在数据分析中排错中比较常用。也可以利用数据库的集合操作来实现此功能。
 
五、自然连接(NATURAL INNER JOIN):自然连接无需指定连接列,SQL会检查两个表中是否相同名称的列,且假设他们在连接条件中使用,并且在连接条件中仅包含一个连接列。不允许使用ON语句,不允许指定显示列,显示列只能用*表示(ORACLE环境下测试的)。对于每种连接类型(除了交叉连接外),均可指定NATURAL。
SELECT * FROM ORDERS O NATURAL INNER JOIN CUSTOMERS C;

六、SQL查询的基本原理:两种情况介绍。             第一、单表查询:根据WHERE条件过滤表中的记录,形成中间表(这个中间表对用户是不可见的);然后根据SELECT的选择列选择相应的列进行返回最终结果。 第二、两表连接查询:对两表求积(笛卡尔积)并用ON条件和连接连接类型进行过滤形成中间表;然后根据WHERE条件过滤中间表的记录,并根据SELECT指定的列返回查询结果。 第三、多表连接查询:先对第一个和第二个表按照两表连接做查询,然后用查询结果和第三个表做连接查询,以此类推,直到所有的表都连接上为止,最终形成一个中间的结果表,然后根据WHERE条件过滤中间表的记录,并根据SELECT指定的列返回查询结果。理解SQL查询的过程是进行SQL优化的理论依据。
 
七、ON后面的条件(ON条件)和WHERE条件的区别:
ON条件:是过滤两个链接表笛卡尔积形成中间表的约束条件。
WHERE条件:在有ON条件的SELECT语句中是过滤中间表的约束条件。在没有ON的单表查询中,是限制物理表或者中间查询结果返回记录的约束。在两表或多表连接中是限制连接形成最终中间表的返回结果的约束。
从这里可以看出,将WHERE条件移入ON后面是不恰当的。推荐的做法是:ON只进行连接操作,WHERE只过滤中间表的记录。

八、总结
连接查询是SQL查询的核心,连接查询的连接类型选择依据实际需求。如果选择不当,非但不能提高查询效率,反而会带来一些逻辑错误或者性能低下。

6.3.4 子查询
子查询
子查询:一个 SELECT 语句嵌套在另一个 SELECT 语句中。
父查询
Select <Column Name> From Table
=操作符
WHERE <Column Name> =
子查询
Select <Column Name> From <Table> WHERE <Column> =<Criteria>
子查询实例
1.父查询传送列值给子查询
2.子查询获取父查询传送的列值
3.子查询返回查询值给父查询
4.父查询传送下一行的列值给子查询(重复1-3步)
5.返回第一步

实例
USE northwind
SELECT orderid, customerid
FROM orders AS or1
WHERE 20 < (SELECT quantity
FROM [order details] AS od
WHERE or1.orderid = od.orderid
AND od.productid = 23)
GO

嵌套子查询
   子查询自身可以包括一个或多个子查询。一个语句中可以嵌套任意数量
的子查询.

相关子查询
    许多查询都可以通过执行一次子查询并将结果值代入外部查询的 WHERE 子句进行评估。  在包括相关子查询(也称为重复子查询)的查询中,子查询依靠外部查询
获得值。

示例
USE pubs
SELECT au_lname, au_fname FROM authors
WHERE 100 IN
(SELECT royaltyper FROM titleauthor
WHERE titleauthor.au_ID = authors.au_id)
在子查询中使用别名许多其中的子查询和外部查询引用同一表的语句可被表述为自联接

在子查询中使用IN 或 NOT IN
通过 IN(或 NOT IN)引入的子查询结果是一列零值或更多值。子查询返回结果之后,外部查询将利用这些结果。例如
USE pubs
SELECT pub_name
FROM publishers
WHERE pub_id IN
(SELECT pub_id
FROM titles
WHERE type = 'business')
在子查询中使用UPDATE、DELETE 和 INSERT 语句
子查询可以嵌套在 UPDATE、DELETE 和 INSERT 语句以及 SELECT 语句中。例如
UPDATE titles
SET price = price * 2
WHERE pub_id IN
(SELECT pub_id
FROM publishers
WHERE pub_name = 'New Moon Books')

在子查询中使用比较运算符
子查询可由一个比较运算符(=、< >、>、> =、<、! >, ! < 或 < =)引入。
示例
USE pubs
SELECT DISTINCT title
FROM titles
WHERE price >
(SELECT MIN(price)
FROM titles)
使用 EXISTS 和 NOT EXISTS
EXISTS 用于检查子查询返回的行是否存在
该子查询实际上并不返回任何数据,而是返回 TRUE 或 FALSE
示例
USE pubs
SELECT au_lname, au_fname
FROM authors
WHERE exists
(SELECT *
FROM publishers
WHERE authors.city = publishers.city)


 


 

posted @ 2012-10-29 18:07  优秀程序缘  阅读(125)  评论(0编辑  收藏  举报