在PostgreSQL中将多对多关系转换为一对多关系

时间:2012-08-28 01:45:19

标签: sql postgresql database-design many-to-many one-to-many

我在foobar之间建立了多对多,以foo_barfoo_id作为表格bar_id

我现在想把它建模为一对多(我的数据允许)。

我已向foo_id添加了bar列,但现在我想迁移我的数据。所以,我想

UPDATE bar SET foo_id = f where id = b;

每个fb对来自

SELECT foo_id AS f, bar_id AS b FROM foo_bar;

是否可以在SQL(特别是PostgreSQL 9.0)中执行此操作?

我知道如果只有一个值,如何在UPDATE中执行子SELECT,但在这种情况下难以理解如何操作。

3 个答案:

答案 0 :(得分:5)

UPDATE bar b
SET    foo_id = fb.foo_id
FROM   foo_bar fb
WHERE  fb.bar_id = b.bar_id;

如果一个bar应该有多行(根据您的描述,您不应该这样做),一行将被多次更新,结果是任意的。

这种形式的查询通常比相关子查询表现得更好。

请注意,bar的主键应该真正命名为bar_id - 我在查询中使用该名称。

答案 1 :(得分:3)

您仍然可以在UPDATE语句中加入表格,尝试

UPDATE  bar a
SET     foo_id = c.foo_id
FROM    (
            SELECT foo_id, bar_id
            FROM foo_bar
        ) c
WHERE   a.id = c.bar_id

或仅仅作为

UPDATE  bar a
SET     foo_id = c.foo_id
FROM    foo_bar c
WHERE   a.id = c.bar_id

答案 2 :(得分:2)

如果你真的有一对多的关系,那么对于一个给定的栏你所采用的foo值无关紧要 - 只有一个或它们都是相同的。

您可以执行以下操作:

update bar
    set foo_id = (select max(foo_id) from foo_bar where foo_bar.bar_id = bar.id)

子查询将结果限制为单个值。