2013-07-16 60 views
1

有一个表像这样:Mysql的更新行,如果我的唯一的匹配结果

Item 
--------- 
id 
parentId 
name 
inventoryNumber 

我需要更新inventoryNumber当且仅当该行...

  1. 的parentId = 12345
  2. 名字符串完全匹配给定的字符串“的 敏捷的棕色狐狸”
  3. 行是匹配前两个 标准才行。

我相信我知道如何做到这一点,如果我只是做一个选择......

SELECT * FROM Item WHERE parentId=12345 
AND name LIKE 'The quick brown fox' HAVING count(*)=1 

,但我需要更新的行...

UPDATE Item SET inventoryNumber = 456 WHERE这是只有行parentId = 12345,唯一的行,其中name ='快速棕色狐狸'

我有大约5000这些行更新,所以它会大大减少我的工作量,如果我可以得到一种在单个语句中更新的方法。这可以做到吗?

更新:我已经试图把这个子查询,如:

UPDATE Item SET inventoryNumber = 456 WHERE id IN (
    SELECT id 
    FROM Item 
    WHERE parentId = 12345 AND name LIKE 'The quick brown fox' HAVING count(*)=1 
); 

但我从MySQL得到一个错误,当我做到这一点:“你不能指定目标表‘项目’的更新中FROM子句:

回答

4

如何使用subquery

编辑

CREATE TABLE Item_tmp LIKE Item; 
INSERT INTO Item_tmp SELECT * FROM Item; 

UPDATE Item SET inventoryNumber = 456 WHERE id IN (
    SELECT id 
    FROM Item_tmp 
    WHERE parentId = 12345 AND name LIKE 'The quick brown fox' HAVING count(*)=1 
); 
+0

我试过了,我得到一个错误...你不能指定目标表“项目”的更新FROM子句 – kasdega

+0

再次看看kasdega。我希望它能解决你的问题。干杯。 – medina

+0

我的表格非常庞大,所以我限定了INSERT INTO语句,并且必须更新update/select语句才能找到索引,但除此解决方案之外。谢谢! – kasdega

0

试试这个: -

Update Item set inventoryNumber = 456 where parentId=12345 and name = "The quick brown fox" group by parentId,name having count(*) =1 
0

这里是一个working demo on SQL Fiddle

它使用该SQL查询:

  • 最内层查询:

    UPDATE Item SET Item.inventoryNumber = 200 
    WHERE Item.id IN (
        SELECT A.id FROM (
        SELECT * FROM Item i GROUP BY i.parentId, i.name HAVING COUNT(*)=1 
    ) AS A WHERE A.parentId = 12345 AND A.name = 'The quick brown fox' 
    ) 
    

    查询明细使用GROUP BY选择唯一的行(根据您的标准#3)

  • 下一页:根据您的标准筛选出行#1和#2
  • 使用UPDATEWHERE子句中的结果。
0

Hers是一个使用CTE和Window函数的解决方案,以确保更新源中行的唯一性。在这个例子中,我们使用学生表中的id来更新主表,他们在名称和DOB上匹配,但只有在更新源中有一行时才会匹配。它运行很快(2秒,77K更新,tblMaster 100K行,在tblStudent 225K行)

;WITH CTE (StudentId, Fname, Mname, LName, DOB, RowCnt) 
    as (
    SELECT StudentId, FirstName, MiddleName, LastName, DateOfBirth as DOB, SUM(1) OVER (Partition By FirstName, ISNULL(Left(MiddleName,1), ''), LastName, DateOfBirth) as RowCnt 
    FROM tblStudent 
    ) 
    UPDATE tblMaster 
     SET ID = StudentID, MatchType = 'Exact' 
    FROM CTE 
    WHERE (ID = 0 OR ID IS NULL) 
     AND DateOfBirth = DOB 
     AND FirstName = Fname 
     AND LastName = LName 
     AND (MiddleName is Null OR Mname is Null OR Left(MiddleName, 1) = LEFT(Mname,1)) 
     AND RowCnt = 1