SQL query to find record with ID not in another table

后端 未结 6 1597
眼角桃花
眼角桃花 2020-12-02 09:02

I have two tables with binding primary key in database and I desire to find a disjoint set between them. For example,

  • Table1 has columns (ID
相关标签:
6条回答
  • 2020-12-02 09:19

    Use LEFT JOIN

    SELECT  a.*
    FROM    table1 a
                LEFT JOIN table2 b
                    on a.ID = b.ID
    WHERE   b.id IS NULL
    
    0 讨论(0)
  • 2020-12-02 09:26

    Fast Alternative

    I ran some tests (on postgres 9.5) using two tables with ~2M rows each. This query below performed at least 5* better than the other queries proposed:

    -- Count
    SELECT count(*) FROM (
        (SELECT id FROM table1) EXCEPT (SELECT id FROM table2)
    ) t1_not_in_t2;
    
    -- Get full row
    SELECT table1.* FROM (
        (SELECT id FROM table1) EXCEPT (SELECT id FROM table2)
    ) t1_not_in_t2 JOIN table1 ON t1_not_in_t2.id=table1.id;
    
    0 讨论(0)
  • 2020-12-02 09:26
    SELECT COUNT(ID) FROM tblA a
    WHERE a.ID NOT IN (SELECT b.ID FROM tblB b)    --For count
    
    
    SELECT ID FROM tblA a
    WHERE a.ID NOT IN (SELECT b.ID FROM tblB b)    --For results
    
    0 讨论(0)
  • 2020-12-02 09:28

    Try this

    SELECT ID, Name 
    FROM   Table1 
    WHERE  ID NOT IN (SELECT ID FROM Table2)
    
    0 讨论(0)
  • 2020-12-02 09:37

    Keeping in mind the points made in @John Woo's comment/link above, this is how I typically would handle it:

    SELECT t1.ID, t1.Name 
    FROM   Table1 t1
    WHERE  NOT EXISTS (
        SELECT TOP 1 NULL
        FROM Table2 t2
        WHERE t1.ID = t2.ID
    )
    
    0 讨论(0)
  • 2020-12-02 09:42

    There are basically 3 approaches to that: not exists, not in and left join / is null.

    LEFT JOIN with IS NULL

    SELECT  l.*
    FROM    t_left l
    LEFT JOIN
            t_right r
    ON      r.value = l.value
    WHERE   r.value IS NULL
    

    NOT IN

    SELECT  l.*
    FROM    t_left l
    WHERE   l.value NOT IN
            (
            SELECT  value
            FROM    t_right r
            )
    

    NOT EXISTS

    SELECT  l.*
    FROM    t_left l
    WHERE   NOT EXISTS
            (
            SELECT  NULL
            FROM    t_right r
            WHERE   r.value = l.value
            )
    

    Which one is better? The answer to this question might be better to be broken down to major specific RDBMS vendors. Generally speaking, one should avoid using select ... where ... in (select...) when the magnitude of number of records in the sub-query is unknown. Some vendors might limit the size. Oracle, for example, has a limit of 1,000. Best thing to do is to try all three and show the execution plan.

    Specifically form PostgreSQL, execution plan of NOT EXISTS and LEFT JOIN / IS NULL are the same. I personally prefer the NOT EXISTS option because it shows better the intent. After all the semantic is that you want to find records in A that its pk do not exist in B.

    Old but still gold, specific to PostgreSQL though: https://explainextended.com/2009/09/16/not-in-vs-not-exists-vs-left-join-is-null-postgresql/

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