0

我使用以下查询:

update a left join b on a.type = b.type and a.name like b.pattern set a.b_id = b.id, a.flags = 1 where a.flags = 0;

b.type 和 b.name 被定义为索引,这意味着 MySQL 尝试匹配这个条件:

order by b.type, b.pattern

是否可以仅将索引用于实际匹配,而不用于 order by-statement?

以供参考:

一个以上的 b 记录可以匹配一个 a 记录,但只能使用具有最低 id 的 b 记录。

问题是,MySQL 不支持在使​​用连接的更新中设置用户定义的顺序语句。如果支持此功能,我可以轻松添加到最后:

按 b.id 订购

是否可以在不使用选择子查询(作为连接)的情况下解决问题,以实现具有多个表的更新中的字段集顺序?

4

1 回答 1

0

您不应该依赖于应用于重复值的任何特定顺序(实际上更像是“优先级”),因为无论是否涉及索引,DBMS 都可以自由使用手头的任何一个。

相反,您应该使用子查询来仅选择b要使用的行。请注意,这不是Order by,而是Group by,因为 DBMS 在测试连接条件后仍然可以选择以它喜欢的任何顺序应用行。对于您问题中的简化案例,它看起来像这样:

Update a 
Left Join
( 
    Select type, pattern, min(id) as min_id 
    from b 
    group by type, pattern 
) as x
On a.type = x.type and a.name like x.pattern
Set a.b_id = x.min_id, a.flags = 1
Where a.flags=0;

更新:由于您已经澄清您需要具有最低 ID 的整行,因此子查询变得相当复杂 - 您必须首先找到匹配的最低 ID,然后获取该行的详细信息。为了可读性,您可以将其分为两个步骤,使用临时表,尽管具有相同内容的子查询是等效的。

-- Find "best" match in b for each row in a
Select a.id, min(b.id) as min_b_id
From a 
Left Join b

-- Apply as many join conditions as required here
On a.type = b.type and a.name like b.pattern

-- Only calculate for those rows you wish to update
Where a.flags = 0

Group by a.id

然后,该表(或子查询)需要连接到a(以查找要更新的行)和b(以查找要更新的完整详细信息)。

于 2013-06-02T21:57:47.057 回答