MySQL更新:使用索引进行左连接,但忽略顺序依次

时间:2013-06-02 21:41:15

标签: mysql join indexing sql-update

我使用以下查询:

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

是否可以仅将索引用于实际匹配,用于按顺序排序?

供参考:

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

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

按b.id排序

是否可以在不使用的情况下解决问题 select-Subquery(作为连接)来实现具有多个表的更新中的字段集顺序?

1 个答案:

答案 0 :(得分: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(以查找要更新的完整详细信息)。< / p>