【问题标题】:SQL query to select unreferenced rows用于选择未引用行的 SQL 查询
【发布时间】:2009-02-05 12:26:27
【问题描述】:

我有一个脑死亡的时刻...我有两个表描述为:

CREATE TABLE table_a (
    id             INTEGER          PRIMARY KEY AUTO_INCREMENT,
    name           VARCHAR(255)     NOT NULL
    UNIQUE (name))

CREATE TABLE table_b (
    id             INTEGER          PRIMARY KEY AUTO_INCREMENT,
    a_key          INTEGER          NOT NULL,
    other_stuff    VARCHAR(255)     NOT NULL,
    FOREIGN KEY(a_key)  REFERENCES table_a(id)
         ON DELETE CASCADE)

如何从 table_a 中选择在 table_b.a_key 中没有条目的所有行?

【问题讨论】:

    标签: sql mysql


    【解决方案1】:
    SELECT table_a.*
    FROM table_a
        LEFT JOIN table_b
            ON table_a.id = table_b.a_key
    WHERE table_b.id IS NULL
    

    【讨论】:

      【解决方案2】:

      天真地,您可以使用 NOT EXISTS 子查询:

      SELECT A.*
      FROM table_a A
      WHERE NOT EXISTS (
        SELECT 1
        FROM table_b B
        WHERE B.a_key = A.id
      )
      

      您也可以尝试外部联接。但它们通常会在内部针对相同的查询进行优化。

      【讨论】:

        【解决方案3】:
        SELECT 
        table_a.* 
        FROM table_a 
        LEFT JOIN table_b 
        ON table_a.id = table_b.a_key 
        WHERE b.id IS NULL;
        

        这会在 table_a 和 table_b 上执行 JOIN,如果 JOIN 找不到 table_b 的连接结果,它会打印 table_a 的相应行条目。

        【讨论】:

          【解决方案4】:

          如果是 SQL server 2005+ 你可以试试 EXCEPT

          SELECT id
          FROM table_a
          EXCEPT
          SELECT a_key
          FROM table_b;
          

          【讨论】:

            【解决方案5】:
            select a.*
            from table_a a
            where a.id not in (select b.a_key from table_b b where b.a_key = a.id)
            

            【讨论】:

            • 值得注意的是,当子选择返回一个包含 NULL 值的列表时,NOT IN (...) 会巧妙地失败。在这种情况下它不会发生(a_key 被定义为 INT NOT NULL),但这是我在这种类型的查询中避免它的原因。
            • NOt in 通常也比左连接慢
            猜你喜欢
            • 2011-02-20
            • 2018-01-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多