连接查询中用来连接连个表的条件称为连接条件或连接谓词。其形式为:
[<表1>].<列名1><连接运算符>[<表2>].<列2>
常见的连接运算符包括
1、比较运算符:=、>、<、>=、<=、!=、between和and。
2、逻辑运算符:not、and、or。
3、使用between和and连接查询形式为[<表1>].<列名1>
1、内连接:表中的行互相连接。结果集的行数等于每个表满足条件的行数的乘积,参与连接的表示平等的。
2、外连接:参与连接的表有主次之分,主表的每一行数据去匹配从表的数据列,符合连接条件的数据将直接返回到结果集中,不符合连接条件的数据列将以null填充后返回到结果集中,其中外连接又分左外连接、右外连接和全连接3种。
(一)、等值连接查询
select p.*,c.* from country as c,person as p where c.countryid = p.countryid
等上面的等值连接中,两张表都有countryid字段,因此查出来的结果中就会有两列countryid
(二)、在等值结果中消除数据就是自然连接
select p.name,c.countryname from country as c,person as p where c.countryid = p.countryid
(三)、自身连接
一个数据表自己与自己建立连接称为自身连接
1、内连接查询的语法结构如下:
select <属性或表达式列表> from <表名> [inner] join <表名> on <连接条件> [ where <限定条件> ]
inner可以省略,当只见到join时就是省略了inner。内连接就是传统的连接操作,这里用on子句指定连接条件,用where子句指定其他限定条件:
select p.name,c.countryname from country as c inner join person p on p.countryid = c.countryid
1、左外连接查询的语法结构:
select <属性或表达式列表> from <表名> left outer join <表名> on <连接条件> [ where <限定条件> ]
如:
select p.name,c.countryname from country as c left join person p on p.countryid = c.countryid
在结果表中包含第一个表中满足条件的所有记录,如果是在连接连接上匹配的记录,则第二个表返回相应值,否则第二个表返回null。也就是说,不管第二个表有没有记录都会第一个表的所有字段都会返回,这就是外连接与内连接的区别。
1、右外连接查询的语法结构如下:
select <属性或表达式列表> from <表名> right outer join <表名> on <连接条件> [ where <限定条件> ]
如:
select p.name,c.countryname from country as c right join person p on p.countryid = c.countryid
在结果表中包含第二个表中满足条件的所有记录。如果是在连接条件上匹配的记录,则第一个表返回相应值,否则第一个表返回null。
1、全外连接查询的语法结构如下:
select <属性或表达式列表> from <表名> full outer join <表名> on <连接条件> where <限定条件>]
如:
select p.name,c.countryname from country as c full join person p on p.countryid = c.countryid
在结果表中包含两个表中满足条件的所有记录。如果是在连接条件上匹配的元组,则另一个表返回相应则,没有则返回null。
交叉连接Corss join,用于将第一张表的所有记录与第二张表的所有记录组合一次并返回,这个东西在生成测试数据库时很有用,例如,你定义7个姓,7个名,再交叉连接就能够产生49条记录。
如有如下表:姓氏表
名字表:
执行如下SQL语句:
select LastName + firstname from name2 cross join name1
结果如下:
union是一个特殊的运算符,用于将两个或两个以上的查询产生一个结果集。join将信息水平连接(添加更多列),而union将信息垂直连接(添加更多行)。
当使用union处理查询时,要注意以下几个关键点。
(1)、所有union的查询必须在select列表中有相同的列数。即如果第一个查询有3个列数,第二个查询也要只有3个列数。
(2)、union返回结果的标题集仅从第一个查询中获得,无论第二个查询如何命名或取别名都不会更改。
(3)、查询中对应的列的数据类型必须隐式一致。注意不要求完全一致,只需要隐式一致。
(4)、与其他非union不同,union的默认返回选项为distinct,而不是all。union all语句与union的不同点仅仅在于遇到相同的记录,全部保留而已。
例如还是用第7条的例子,执行如下语句:
select * from name1 union select * from name2
返回结果为:
由于union默认是distinct查询,因此想要获得所有的记录时,可以用union all,这样就算上述例子中两个表都有'王',也会两条记录一起返回。
现在来看一下综合示例:
为了展示一下,建了两张表,并添加了几条记录,如下:
person表
country表
1、查询一个列表,该列表要包含国家名称列表与该国家下的person总数。
select c.countryname,count(p.id) from country as c inner join person as p on c.countryid = p.countryid group by c.countryname
输出结果:
现在在来加一个条件,要求人口数按升序排列:
select c.countryname,count(p.id) as co from country as c inner join person as p on c.countryid = p.countryid group by c.countryname order by co asc
输出结果:
再加一个条件,要求只输出person数大于2的记录:
select c.countryname,count(p.id) as co from country as c inner join person as p on c.countryid = p.countryid group by c.countryname having count(p.id) > 2 order by co asc
输出结果为:
1)内联接:
内联接使用比较运算符(使用像 = 或 <> 之类的比较运算符)根据每个表共有的列的值匹配两个表中的行,根据这两张表中相同列的条件,得出其 交集。例如: 检索 students和courses表中学生标识号相同的所有行。
有两种,显式的和隐式的,返回连接表中符合连接条件和查询条件的数据行(链接表就是数据库在做查询形成的中间表)。
隐式的内连接:
没有INNER JOIN,形成的中间表为两个表的笛卡尔积。
一般称为内连接,有INNER JOIN,形成的中间表为两个表经过ON条件过滤后的笛卡尔积。
2)左向外联:
是用的是LEFT JOIN或LEFT OUTER JOIN 连接语句。
根据两张表的关系(外键关联),笛卡尔过滤,也就是求出两张表的交集, 如果交集中,左边表的行, 在右边表中没有匹配,则该条记录左边表有数据, 右边表所有的字段都为null。
左外连接时,写where语句的独立查询条件: 规则, on后面写连接条件, where后写查询条件
3)右外连接:
RIGHT JOIN 或 RIGHT OUTER JOIN 连接语句
和左外连接是相反的,查出的两张表的交集, 如果这条记录,右边表有数据,左边表没有, 则把左边表的字段都设置为null。
案例:
内连接查询:
左连接 :
对于SQL查询的基本原理:
1)单表查询:根据WHERE条件过滤表中的记录,然后根据SELECT的选择列选择相应的列进行返回最终结果。
2)两表连接查询: 在on后面写连接条件, 在where后面写过滤的查询条件,然后再根据SELECT指定的列返回查询结果。
3)多表连接查询:先对第一个和第二个表按照两表连接做查询,然后用查询结果和第三个表做连接查询,以此类推,直到所有的表都连接上为止,最终形成一个中间的结果表,然后根据WHERE条件过滤中间表的记录,并根据SELECT指定的列返回查询结果。
关于on条件和where条件的区别:
ON条件:是过滤两个链接表笛卡尔积形成中间表的约束条件。
WHERE条件:ON只进行连接操作,WHERE只过滤中间表的记录。
对于连接类型的选择: 在实际运用中如果连接类型选择不当, 不但出现效率低并且可能还会出现逻辑的错误
1、 查两表关联列相等的数据用内连接
2、 Col_L是Col_R的子集时用右外连接。(左边表是右边表的子集,用右外)
3、 Col_R是Col_L的子集时用左外连接。(右边表是左边表的子集, 用左外)
4、 求差操作的时候用联合查询。
并且,多个表查询的时候,这些不同的连接类型可以写到一块
例如:
通过连接运算符可以实现多个表查询。连接是关系数据库模型的主要特点,是它区别于其它类型 数据库管理系统的一个标志。连接可以在SELECT 语句的FROM子句或WHERE子句中建立,在FROM子句中指出连接时有助于将连接操作与WHERE子句中的搜索条件区分开来。一般来说,连接查询比嵌套查询的效率高一点。所以,在Transact-SQL中推荐使用这种方法。
如果 A 和 B 是两个集合,它们的交叉连接就记为: A × B.
例如: SELECT * FROM press CROSS JOIN authors
等价于:SELECT * FROM press,authors
查询结果:
外连接并不要求连接的两表的每一条记录在对方表中都一条匹配的记录. 连接表保留所有记录 -- 甚至这条记录没有匹配的记录也要保留. 外连接可依据连接表保留左表, 右表或全部表的行而进一步分为左外连接, 右外连接和全连接.在标准的 SQL 语言中, 外连接没有隐式的连接符号.
左外连接会返回左表的所有记录和右表中匹配记录的组合(如果右表中无匹配记录, 来自于右表的所有列的值设为 NULL). 如果左表的一行在右表中存在多个匹配行, 那么左表的行会复制和右表匹配行一样的数量, 并进行组合生成连接结果.
例如:SELECT * FROM press LEFT OUTER JOIN authors ON press.id = authors.press_id
查询结果:
右外连接, 亦简称右连接, 它与左外连接完全类似, 只不过是作连接的表的顺序相反而已.右连接操作返回右表的所有行和这些行在左表中匹配的行(没有匹配的, 来源于左表的列值设为 NULL).
例如:SELECT * FROM press RIGHT OUTER JOIN authors ON press.id= authors.press_id
等价于:SELECT * FROM authors LEFT OUTER JOIN press ON press.id= authors.press_id
查询结果:
实际上显式的右连接很少使用, 因为它总是可以被替换成左连接--换换表的位置就可以了,所以上面两条语句是等价的。
全连接是左右外连接的并集. 连接表包含被连接的表的所有记录, 如果缺少匹配的记录, 即以 NULL 填充.。一些数据库系统(如 MySQL)并不直接支持全连接, 但它们可以通过左右外连接的并集(参: union)来模拟实现
例如:SELECT * FROM press FULL OUTER JOIN authors ON press.id= authors.press_id
查询结果:
自身连接是指同一个表自己与自己进行连接。既可以用内连接,也可以用外连接。
例如:SELECT * FROM authors a1 LEFT JOIN authors a2 ON a2.press_id = a1.id
查询结果:
参考链接:http://www.cnblogs.com/worksguo/articles/1030214.html
http://zh.wikipedia.org/wiki/连接_(SQL)
参考:http://blog.csdn.net/nieson2012/article/details/45789461
http://www.cnblogs.com/kissdodog/archive/2013/06/03/3116233.html