1

我有一张这样的桌子:

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

当且仅当行...时,我才需要更新inventoryNumber

  1. 父 ID = 12345
  2. 名称字符串与给定字符串“The quick brown fox”完全匹配
  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='The quick brown fox' 的唯一行

我有大约 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 子句中指定目标表 'item' 进行更新:

4

4 回答 4

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
);
于 2013-07-16T05:57:47.430 回答
0

尝试这个:-

Update Item set inventoryNumber = 456 where parentId=12345 and name = "The quick brown fox" group by parentId,name  having count(*) =1
于 2013-07-16T06:12:01.570 回答
0

这是一个关于 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在 的子句中使用结果UPDATE
于 2013-07-16T07:18:43.533 回答
0

Hers 是一种解决方案,它使用带有 Window 函数的 CTE 来确保更新源中行的唯一性。在此示例中,我们使用学生表中的 id 更新主表,它们在 name 和 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
于 2016-07-01T21:48:34.057 回答