sql jion

摘要:
我们知道SQLJoin语法有很多内部、外部和左侧语法。有时,不清楚“选择”的结果集是什么样子的。一篇关于CodingHorror的文章通过Venndigrams解释了SQL连接。我感觉很清楚,很容易理解,转过身来。假设我们有两张桌子。共有四条记录,其中两条相同,如下所示:idnameidname-------------1Pirate1Rutaga2Monkey2Pirate3Inja3DarthVader4Pagetti4Inja让我们看看不同的Join会产生什么结果。
sql jion第1张     A Visual Explanation of SQL Joins

I thought Ligaya Turmelle's post on SQL joins was a great primer for novice developers. Since SQL joins appear to be set-based, the use of Venn diagrams to explain them seems, at first blush, to be a natural fit. However, like the commenters to her post, I found that the Venn diagrams didn't quite match the SQL join syntax reality in my testing.

I love the concept, though, so let's see if we can make it work. Assume we have the following two tables. Table A is on the left, and Table B is on the right. We'll populate them with four records each.

id name       id  name
-- ----       --  ----
1  Pirate     1   Rutabaga
2  Monkey     2   Pirate
3  Ninja      3   Darth Vader
4  Spaghetti  4   Ninja

Let's join these tables by the name field in a few different ways and see if we can get a conceptual match to those nifty Venn diagrams. 


















SELECT * FROM TableA
INNER JOIN TableB
ON TableA.name = TableB.name

id  name       id   name
--  ----       --   ----
1   Pirate     2    Pirate
3   Ninja      4    Ninja

Inner join produces only the set of records that match in both Table A and Table B.


Venn diagram of SQL inner join
SELECT * FROM TableA
FULL OUTER JOIN TableB
ON TableA.name = TableB.name

id    name       id    name
--    ----       --    ----
1     Pirate     2     Pirate
2     Monkey     null  null
3     Ninja      4     Ninja
4     Spaghetti  null  null
null  null       1     Rutabaga
null  null       3     Darth Vader

Full outer join produces the set of all records in Table A and Table B, with matching records from both sides where available. If there is no match, the missing side will contain null.


Venn diagram of SQL cartesian join
SELECT * FROM TableA
LEFT OUTER JOIN TableB
ON TableA.name = TableB.name

id  name       id    name
--  ----       --    ----
1   Pirate     2     Pirate
2   Monkey     null  null
3   Ninja      4     Ninja
4   Spaghetti  null  null

Left outer join produces a complete set of records from Table A, with the matching records (where available) in Table B. If there is no match, the right side will contain null.


Venn diagram of SQL left join
SELECT * FROM TableA
LEFT OUTER JOIN TableB
ON TableA.name = TableB.name
WHERE TableB.id IS null

id  name       id     name
--  ----       --     ----
2   Monkey     null   null
4   Spaghetti  null   null

To produce the set of records only in Table A, but not in Table B, we perform the same left outer join, then exclude the records we don't want from the right side via a where clause


join-left-outer.png
SELECT * FROM TableA
FULL OUTER JOIN TableB
ON TableA.name = TableB.name
WHERE TableA.id IS null
OR TableB.id IS null

id    name       id    name
--    ----       --    ----
2     Monkey     null  null
4     Spaghetti  null  null
null  null       1     Rutabaga
null  null       3     Darth Vader

To produce the set of records unique to Table A and Table B, we perform the same full outer join, then exclude the records we don't want from both sides via a where clause


join-outer.png

There's also a cartesian product or cross join, which as far as I can tell, can't be expressed as a Venn diagram:

SELECT * FROM TableA
CROSS JOIN TableB

This joins "everything to everything", resulting in 4 x 4 = 16 rows, far more than we had in the original sets. If you do the math, you can see why this is a very dangerous join to run against large tables.

对于SQL的Join,在学习起来可能是比较乱的。我们知道,SQL的Join语法有很多inner的,有outer的,有left的,有时候,对于Select出来的结果集是什么样子有点不是很清楚。Coding Horror上有一篇文章(实在不清楚为什么Coding Horror也被墙)通过 文氏图 Venn diagrams 解释了SQL的Join。我觉得清楚易懂,转过来。

假设我们有两张表。

  • Table A 是左边的表。
  • Table B 是右边的表。

其各有四条记录,其中有两条记录是相同的,如下所示:

id name       id  name
-- ----       --  ----
1  Pirate     1   Rutabaga
2  Monkey     2   Pirate
3  Ninja      3   Darth Vader
4  Spaghetti  4   Ninja

下面让我们来看看不同的Join会产生什么样的结果。

SELECT * FROM TableA
INNER JOIN TableB
ON TableA.name = TableB.name

id  name       id   name
--  ----       --   ----
1   Pirate     2    Pirate
3   Ninja      4    Ninja

Inner join
产生的结果集中,是A和B的交集。

Venn diagram of SQL inner join

SELECT * FROM TableA
FULL OUTER JOIN TableB
ON TableA.name = TableB.name

id    name       id    name
--    ----       --    ----
1     Pirate     2     Pirate
2     Monkey     null  null
3     Ninja      4     Ninja
4     Spaghetti  null  null
null  null       1     Rutabaga
null  null       3     Darth Vader

Full outer join 产生A和B的并集。但是需要注意的是,对于没有匹配的记录,则会以null做为值。

Venn diagram of SQL cartesian join

SELECT * FROM TableA
LEFT OUTER JOIN TableB
ON TableA.name = TableB.name

id  name       id    name
--  ----       --    ----
1   Pirate     2     Pirate
2   Monkey     null  null
3   Ninja      4     Ninja
4   Spaghetti  null  null

Left outer join 产生表A的完全集,而B表中匹配的则有值,没有匹配的则以null值取代。

Venn diagram of SQL left join

SELECT * FROM TableA
LEFT OUTER JOIN TableB
ON TableA.name = TableB.name
WHERE TableB.id IS null 

id  name       id     name
--  ----       --     ----
2   Monkey     null   null
4   Spaghetti  null   null

产生在A表中有而在B表中没有的集合。

join-left-outer.png

SELECT * FROM TableA
FULL OUTER JOIN TableB
ON TableA.name = TableB.name
WHERE TableA.id IS null
OR TableB.id IS null

id    name       id    name
--    ----       --    ----
2     Monkey     null  null
4     Spaghetti  null  null
null  null       1     Rutabaga
null  null       3     Darth Vader

产生A表和B表都没有出现的数据集。

join-outer.png

还需要注册的是我们还有一个是“交差集” cross join, 这种Join没有办法用文式图表示,因为其就是把表A和表B的数据进行一个N*M的组合,即笛卡尔积。表达式如下:

SELECT * FROM TableA
CROSS JOIN TableB

这个笛卡尔乘积会产生 4 x 4 = 16 条记录,一般来说,我们很少用到这个语法。但是我们得小心,如果不是使用嵌套的select语句,一般系统都会产生笛卡尔乘积然再做过滤。这是对于性能来说是非常危险的,尤其是表很大的时候。

(全文完)

免责声明:文章转载自《sql jion》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇标准C程序设计七---32.net framework 2.0安装下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Oracle中的关键字

NVL和COALESCE的区别: nvl(COMMISSION_PCT,0)如果第一个参数为null,则返回第二个参数如果第一个参数为非null,则返回第一个参数 COALESCE(EXPR1,EXPR2,EXPR3...EXPRn)从左往右数,遇到第一个非null值,则返回该非null值。多层判断 第一点区别:从上面可以知道,nvl只适合于两个参数的,C...

ios storyboard全解析 (二)

Add Player 最终的设计看上去像下面这样:#接第一部分:原帖地址简书地址 如果你想了解storyboards,那么你来对地方了.在第一篇文章第一篇文章中,你已经学到了Interface Builder的基本用法来创建和连线多个控制器,以及使用在storyboard中可以通过直接创建自定义的tableViewCell.此次storyboard系列教...

oracle sql日期比较:

共三部分: 第一部分:oracle sql日期比较: http://www.blogjava.net/forker/archive/2007/09/07/143467.html#Post 第二部分:Oracle获取当前日期及日期格式 http://blog.sina.com.cn/s/blog_6168ee920100l2ye.html 第三部分: 获取昨...

关于子查询中的order by子句

关于子查询中能否用order by子句,有以下两种情况: 第一种例如: select a.col1 from a where a.col2 in (select b.col2 from b order by b.col1);这种情况下子查询只是一个集合,并不需要进行order by。 第二种例如: select a.col1, b.col2 from a...

lua table remove元素的问题

当我在工作中使用lua进行开发时,发现在lua中有4种方式遍历一个table,当然,从本质上来说其实都一样,只是形式不同,这四种方式分别是: for key, value in pairs(tbtest) do   XXX   end    for key, value in ipairs(tbtest) do   XXX   end    for i...

MySQL数据库增删改字段(属性)

MySQL数据库的各种操作今天在这里总结一下: 一、增加 1.在已有的表中添加新的字段: 首先是增加表的字段,比如一张表原本没有字段“ Time ”,现在我们要增加这样一个字段,可以用下面的SQL语句实现: alter table +table的名字+ add + 字段名字 + 数据类型+分号,以下SQL在表testTable中插入了2个字段,font和a...