3

我有两张桌子:

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'spermission_lookup_id和同样 for permission_object_id,基于documents.parent_id外键约束。

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

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

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

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

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

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

空白值也是如此。

编辑 2:在我原来的选择/更新查询中犯了一个业余错误。在 WHERE 子句中,我有:

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

我应该有的地方

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

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

4

3 回答 3

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)

手册说 JOIN 子句是可以的,但我很想知道是否有任何区别。

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

于 2012-07-20T15:37:14.870 回答
0

来自任一表的是否有可能permission_lookup_id具有 NULL 值?如果是这样,您可能想尝试使用 NULL 安全运算符:

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)
于 2012-07-20T15:42:43.337 回答
0

尝试在查询中使用内连接而不是左连接,请告诉我您的 id 字段是否具有空值?如果是,那么它需要一种不同的方法

于 2012-07-20T15:44:57.023 回答