如果Mysql是唯一匹配的结果,则Mysql会更新一行

时间:2013-07-16 05:53:48

标签: mysql sql

我有一张这样的表:

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

当且仅当行...

时,我需要更新inventoryNumber
  1. parentId = 12345
  2. name string恰好匹配给定的字符串" The 快速的棕色狐狸"
  3. 该行是唯一与前两个匹配的行 标准。
  4. 我相信如果我只是做一个选择,我知道如何做到这一点......

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

    但我需要更新行...

    UPDATE Item SET inventoryNumber = 456 WHERE 这是parentId = 12345的唯一一行,也是唯一一行名称='快速棕色狐狸'

    我有大约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收到错误"你无法指定目标表' item'用于FROM子句中的更新:

4 个答案:

答案 0 :(得分: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
);

答案 1 :(得分:0)

试试这个: -

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

答案 2 :(得分: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
  • 过滤掉行
  • 使用WHERE的{​​{1}}子句中的结果。

答案 3 :(得分:0)

Hers是一种解决方案,它使用带有Window功能的CTE来确保更新源中行的唯一性。在此示例中,我们使用student表中的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