2013-07-16 40 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