MySQL更新一个表,如果它们不相等,则使用另一个表中的值

时间:2012-07-20 15:29:17

标签: mysql

我有两张桌子:

SELECT
    d.id,
    d.permission_lookup_id,
    d.permission_object_id,
    f.id,
    f.permission_lookup_id,
    f.permission_object_id
FROM
    folders f
LEFT JOIN
    documents d
    ON f.id = d.folder_id
WHERE
    d.permission_lookup_id != f.permission_lookup_id OR
    d.permission_object_id != f.permission_object_id

理论上如果一切顺利,这应该不会返回,但事实并非如此,我收到了成千上万的结果(目前为407,343)。我需要更新documents表,以便permission_lookup_id匹配folders的{​​{1}},同样地permission_lookup_id匹配permission_object_id作为外键约束。

我尝试了以下查询但收效甚微:

documents.parent_id

运行后,它告诉我70,986行受影响,407343行匹配,但我仍然有第一个选择查询的结果。

编辑:以下两个查询都返回0行:

UPDATE folders f LEFT JOIN documents d ON f.id = d.folder_id SET d.permission_lookup_id = f.permission_lookup_id, d.permission_object_id = f.permission_object_id WHERE d.permission_lookup_id != f.permission_lookup_id OR d.permission_object_id != f.permission_object_id

SELECT * FROM folders WHERE permission_lookup_id IS NULL OR permission_object_id IS NULL;

同样适用于空白值。

编辑2:我的原始选择/更新查询中出现了业余错误。在WHERE子句中,我有:

SELECT * FROM documents WHERE permission_lookup_id IS NULL OR permission_object_id IS NULL;

我本应该去哪里

WHERE
    d.permission_lookup_id != f.permission_lookup_id OR
    d.permission_object_id != f.permission_lookup_id

这导致我收到误报,只会导致更新通过并更新每一列,无论是否需要。对不起,感到困惑。

3 个答案:

答案 0 :(得分:0)

这种替代语法怎么样:

UPDATE 
    folders f, documents d
SET
    d.permission_lookup_id = f.permission_lookup_id,
    d.permission_object_id = f.permission_object_id
WHERE
    f.id = d.folder_id AND (
    d.permission_lookup_id != f.permission_lookup_id OR
    d.permission_object_id != f.permission_lookup_id)

The manual说JOIN条款没问题,但我很想知道是否存在差异。

  

前面的示例显示了使用逗号的内部联接   运算符,但多表UPDATE语句可以使用任何类型   SELECT语句中允许join,例如LEFT JOIN。

答案 1 :(得分:0)

两个表中的permission_lookup_id是否有NULL值?如果是这样,您可能想尝试使用NULL-safe运算符:

WHERE
    (NOT d.permission_lookup_id <=> f.permission_lookup_id) OR
    (NOT d.permission_object_id <=> f.permission_lookup_id)

<强>更新

一次尝试一个字段只是为了查看并使用以下语法(这可能需要更长时间才能运行):

UPDATE folders f
SET f.permission_lookup_id =COALESCE((SELECT d.permission_lookup_id FROM documents d
                                      WHERE f.id = d.folder_id
                                      AND d.permission_lookup_id != f.permission_lookup_id),
                                      f.permission_lookup_id)

答案 2 :(得分:0)

尝试在查询中使用内部联接而不是左联接,请告诉我您的id字段是否具有空值?如果是,则需要采用不同的方法