【问题标题】:Remove rows NOT referenced by a foreign key删除未被外键引用的行
【发布时间】:2010-11-20 15:50:24
【问题描述】:

这和this question有点关系:

我有一个带有主键的表,并且我有几个引用该主键的表(使用外键)。我需要从该表中删除行,其中任何其他表(以及一些其他约束)都没有引用主键。

例如:

Group
groupid | groupname
    1   |    'group 1'
    2   |    'group 3'
    3   |    'group 2'
    ... |    '...'

Table1
tableid | groupid | data
    1   |    3    |    ...
    ... |    ...  |    ...

Table2
tableid | groupid | data
    1   |    2    |    ...
    ... |    ...  |    ...

等等。 Group 中的某些行未在任何表中引用,我需要删除这些行。除此之外,我还需要知道如何查找引用 Group 中给定行的所有表/行。

我知道我可以查询每个表并检查 groupid,但由于它们是外键,我想有更好的方法。

顺便说一下,这里使用的是 Postgresql 8.3。

【问题讨论】:

    标签: sql postgresql


    【解决方案1】:
    DELETE
    FROM    group g
    WHERE   NOT EXISTS
            (
            SELECT  NULL
            FROM    table1 t1
            WHERE   t1.groupid = g.groupid
            UNION ALL
            SELECT  NULL
            FROM    table1 t2
            WHERE   t2.groupid = g.groupid
            UNION ALL
            …
            )
    

    【讨论】:

    • 好吧,就像我说的那样,我想避免这种情况。有几个表,名称约定不是标准的,而且速度很慢。由于约束已经到位,我认为必须有更好的方法。
    【解决方案2】:

    在它的核心,SQL 服务器不维护约束的 2-way 信息,因此您唯一的选择是执行如果您要删除该行,服务器会在内部执行的操作:检查每个其他表。

    如果(首先要确定)您的约束是简单的检查并且不带有任何“on delete cascade”类型的语句,您可以尝试从组表中删除所有内容。因此,任何删除的行都不会引用它。否则,你会被 Quassnoi 的回答卡住。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-09
      • 1970-01-01
      相关资源
      最近更新 更多