Opposite of inner join

后端 未结 4 1174
清歌不尽
清歌不尽 2021-01-30 14:16

What will be the opposite of inner join? For a table table Person (int PersonId, varchar PersoName, int AddrId), I want to know the rows in Person with bad Ad

相关标签:
4条回答
  • 2021-01-30 14:42

    An Inner join is not diametric to an Outer Join. They serve different purposes. However, a common pattern to find rows from one table that do not exist in another is to use an Outer Join:

    Select ...
    From Table1
        Left Join Table2
            On Table2.ForeignKeyCol = Table1.PrimaryKeyCol
    Where Table2.PrimaryKeyCol Is Null
    

    This returns all rows from Table1 and any matching rows from Table2 such that if a given Table1 row has no Table2 match, a null for the Table2 columns are returned. By then requiring that a non-nullable column (Table2.PrimaryKeyCol) be Null, I will get all rows from Table1 that do not exist in Table2. Using your example table names we would have something like:

    Select ...
    From Person
        Left Join Address
            On Address.PersonId = Person.Id
    Where Address.Id Is Null
    
    0 讨论(0)
  • 2021-01-30 14:48

    If you consider an inner join as the rows of two tables that meet a certain condition, then the opposite would be the rows in either table that don't.

    For example the following would select all people with addresses in the address table:

    SELECT p.PersonName, a.Address
    FROM people p
    JOIN addresses a
        ON p.addressId = a.addressId
    

    I imagine the "opposite" of this would be to select all of the people without addresses and all addresses without people. However this doesn't seem to be what you are asking, you seem to be interested in just one component of this: all the people without an address in the addresses table.

    For this a left join would be best:

    SELECT p.PersonName
    FROM people p
    LEFT JOIN addresses a
       ON p.addressId = a.addressId
    WHERE a.addressId IS NULL
    

    Note that often some prefer to write it differently as in their opinion it is more readable (however in my experience with large tables it performs worse than the above way):

    SELECT PersonName
    FROM people
    WHERE addressId NOT IN (SELECT addressId FROM addresses)
    
    0 讨论(0)
  • 2021-01-30 14:50

    What will be the opposite of inner join?

    An OUTER join, which can be of three options:

    • LEFT
    • RIGHT
    • FULL

    This is a good visual representation of JOINs

    I want to know the rows in Person with bad AddrId which don't have a row in the Address table.

    Using LEFT JOIN/IS NULL

       SELECT p.*
         FROM PERSON p
    LEFT JOIN ADDRESS a ON a.addrid = p.addrid
        WHERE a.addrid IS NULL
    

    Using NOT EXISTS

    SELECT p.*
      FROM PERSON p
     WHERE NOT EXISTS(SELECT NULL
                        FROM ADDRESS a
                       WHERE a.addrid = p.addrid)
    

    Using NOT IN

    SELECT p.*
      FROM PERSON p
     WHERE p.addrid NOT IN (SELECT a.addrid
                              FROM ADDRESS a)
    
    0 讨论(0)
  • 2021-01-30 14:53

    I think the best solution would be using EXISTS. Like this:

    SELECT * FROM Person P
    WHERE P.AddrId IS NOT NULL 
      AND NOT EXISTS ( SELECT 1 FROM Address A WHERE A.AddrId = P.AddrId )
    

    The query above will return every person that the AddrId is set but does not have a corresponding record in the Address table.

    Obs.: Use the constant 1 in the EXISTS query to avoid table access.

    0 讨论(0)
提交回复
热议问题