zoukankan      html  css  js  c++  java
  • 数据库sql的join多表

    摘录文章

    SQL join 用于根据两个或多个表中的列之间的关系,从这些表中查询数据。注意,join后的数据记录数不一定就是左或右表的简单连接,图表只代表集合关系,在数量上并不准确,如这个条件后结果,数量大于左表总数

    图解SQL Join

    我认为 Ligaya Turmelle 关于 SQL Join 的文章是一篇非常棒的新手入门指南。由于 SQL Join 似乎被默认为基础,同时利用文氏图表来解释它,乍一看似乎是很自然的选择。然而,就像她的文章下面评论里说的,我也发现在实际测试中,文氏图并没有完全符合 SQL Join 语法

    我喜欢这个概念,不过让我们先来看看这是否会在实际中发挥作用。假设我们有以下的两个表格,表A在左边,表B在右边,我们将它们填充每个四条记录。

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

    让我们通过name字段以几个不同的方式连接这些表,看看是否会得到一个概念上匹配那些漂亮的维恩图。

    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的交集。
    A、B交

    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做为值。
    A+B

    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值取代。
    只A

    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中,我们执行相同的Left outer join ,然后通过一个where子句排除我们不想要的右侧记录。
    A非B

    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,我们执行相同的 full outer join ,然后通过一个where子句排除我们不从双方想要的记录。
    非A、B交

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

    SELECT * FROM TableA
    CROSS JOIN TableB
    

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

    SUMMARY


    原文 A Visual Explanation of SQL Joins
    翻译 SegmentFault
    参考 酷壳

    sql(join中on与where区别)

     

    left join :左连接,返回左表中所有的记录以及右表中连接字段相等的记录。

    right join :右连接,返回右表中所有的记录以及左表中连接字段相等的记录。

    inner join: 内连接,又叫等值连接,只返回两个表中连接字段相等的行。

    full join:外连接,返回两个表中的行:left join + right join。

    cross join:结果是笛卡尔积,就是第一个表的行数乘以第二个表的行数。

    关键字: on

    数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户。

    在使用left jion时,on和where条件的区别如下:

    1、 on条件是在生成临时表时使用的条件,它不管on中的条件是否为真,都会返回左边表中的记录。

    2、where条件是在临时表生成好后,再对临时表进行过滤的条件。这时已经没有left join的含义(必须返回左边表的记录)了,条件不为真的就全部过滤掉。

    假设有两张表:

    表1:tab2

    id size
    1 10
    2 20
    3 30

    表2:tab2

    size name
    10 AAA
    20 BBB
    20 CCC

    两条SQL:
    1、select * form tab1 left join tab2 on (tab1.size = tab2.size) where tab2.name=’AAA’
    2、select * form tab1 left join tab2 on (tab1.size = tab2.size and tab2.name=’AAA’)

    第一条SQL的过程:

    1、中间表
    on条件:
    tab1.size = tab2.size

    注意:有4条记录,大于tab1的总记录数)

    tab1.id tab1.size tab2.size tab2.name
    1 10 10 AAA
    2 20 20 BBB
    2 20 20 CCC
    3 30 (null) (null)
       
    2、再对中间表过滤
    where 条件:
    tab2.name=’AAA’
    tab1.id tab1.size tab2.size tab2.name
    1 10 10 AAA
       
    第二条SQL的过程:
    1、中间表
    on条件:
    tab1.size = tab2.size and tab2.name=’AAA’
    (条件不为真也会返回左表中的记录)
    tab1.id tab1.size tab2.size tab2.name
    1 10 10 AAA
    2 20 (null) (null)
    3 30 (null) (null)

    其实以上结果的关键原因就是left join,right join,full join的特殊性,不管on上的条件是否为真都会返回left或right表中的记录,full则具有left和right的特性的并集。 而inner jion没这个特殊性,则条件放在on中和where中,返回的结果集是相同的。

  • 相关阅读:
    1014 Waiting in Line (30)(30 point(s))
    1013 Battle Over Cities (25)(25 point(s))
    1012 The Best Rank (25)(25 point(s))
    1011 World Cup Betting (20)(20 point(s))
    1010 Radix (25)(25 point(s))
    1009 Product of Polynomials (25)(25 point(s))
    1008 Elevator (20)(20 point(s))
    1007 Maximum Subsequence Sum (25)(25 point(s))
    1006 Sign In and Sign Out (25)(25 point(s))
    1005 Spell It Right (20)(20 point(s))
  • 原文地址:https://www.cnblogs.com/Fang3s/p/4720356.html
Copyright © 2011-2022 走看看