2012-07-11 48 views
5

Tôi vừa mới nhận ra rằng tôi đã thu thập dữ liệu sai cho một cột trong bảng của mình. Tôi đã khắc phục vấn đề, tuy nhiên, dữ liệu tôi đã chụp cho đến nay vẫn không chính xác.Làm thế nào để cập nhật dữ liệu một cột bằng cách sử dụng dữ liệu bảng khác TSQL

Hãy tên bảng của tôi TableIWantToCorrectTableWithIDs

Trong TableIWantToCorrect, tôi có một chính nước ngoài để TableWithIDs. Đây là những gì không chính xác.

Tôi có thể sửa dữ liệu bằng cách so sánh chuỗi con của cột trong TableIWantToCorrect với cột ở TableWithIDs.

Vì vậy, hiện nay, tôi có

TableIWantToCorrect

Name   ForeignKey 
123-abc-123  15 
456-def-456  15 
789-ghi-789  15 

TableWithIDs

CompareName id 
abc   1 
def   2 
ghi   3 

Vì vậy, tôi muốn cập nhật TableIWantToCorrect có giá trị ForeignKey đúng khi chuỗi con trong Tên bằng chuỗi con trong So sánh tên. Vị trí của chuỗi con luôn giống nhau vì vậy tôi có thể sử dụng phương thức Substring.

nỗ lực của tôi:

Update TableIWantToCorrect 
SET ForeignKey = 
     (SELECT id 
     FROM TableWithIDs 
     WHERE UPPER(CompareName) = UPPER((SUBSTRING(TableIWantToCorrect.Name, 4, 3))) 

Kết quả:

Subquery trở lại hơn 1 giá trị. Điều này không được phép khi truy vấn con theo sau =,! =, <, < =,>,> = hoặc khi truy vấn con được sử dụng làm một biểu thức. Các tuyên bố này đã bị chấm dứt.

Tôi biết tôi đã làm điều gì đó ngớ ngẩn. Tôi đã làm gì sai ở đây?

+1

bạn inline-truy vấn của bạn đang trở lại hơn là một hàng do đó vấn đề này. Chạy truy vấn này để tìm ra những người được lặp đi lặp lại 'CHỌN CompareName, COUNT (1) \t TỪ TableWithIDs GROUP BY CompareName HAVING COUNT (1)> 1 \t ' – Chandu

+0

Bạn vẫn nhận được lỗi nếu bạn thay đổi subquery để sử dụng 'CHỌN DISTINCT id'? Nếu có nhiều kết quả phù hợp và nó không rõ ràng để sử dụng. –

+0

bản sao có thể có của [UPDATE from SELECT using SQL Server] (http://stackoverflow.com/questions/2334712/update-from-select-using-sql-server) –

Trả lời

13

Lỗi là vì truy vấn con của bạn đang trả về nhiều bản ghi cho UPDATE. Để sửa lỗi này, bạn có thể làm điều này bằng cách sử dụng JOIN với UPDATE

UPDATE t1 
SET ForeignKey = t2.id 
FROM TableIWantToCorrect t1 
INNER JOIN TableWithIDs t2 
    ON UPPER(t2.CompareName) = UPPER(SUBSTRING(t1.Name, 4, 3)) 
+1

Tôi biết điều này đặc biệt là một câu hỏi SQL Server, nhưng nếu bạn muốn tương đương MySQL để làm điều này, hãy thử ở đây: http://stackoverflow.com/a/11709090/403264 – JonRed

2
Update TableIWantToCorrect 
SET ForeignKey = s.id 
FROM TableIWantToCorrect , TableWithIDs as s 
WHERE UPPER(s.CompareName) = UPPER((SUBSTRING(TableIWantToCorrect.Name, 4, 3)) 
+1

Bạn luôn có thể biết ai làm việc trong Oracle, họ không bao giờ sử dụng lệnh nối. ;) – Limey

+1

Thật không may tôi swing ở giữa máy chủ Oracle và Sql vì vậy một số thời gian tôi làm bị lẫn lộn ..!tuy nhiên chúng mang lại kết quả tương tự nhưng vẫn tham gia nên được ưu tiên .http: //stackoverflow.com/questions/1018822/inner-join-on-vs-where-clause – praveen

+1

Tôi đã 10 năm ở Oracle, và tôi đã từng ghét tuyên bố tham gia! Vì một lý do nào đó, tôi luôn thấy khó đọc, nhưng sau nhiều năm trong máy chủ SQL, tôi đã thấy các lỗi của cách của mình và luôn sử dụng các phép nối. – Limey

-1
--CREATE FUNCTION dbo.ufn_FindReports 
--(@InEmpID INTEGER) 
--RETURNS @retFindReports TABLE 
--(
-- EmployeeID int primary key NOT NULL, 
-- FirstName nvarchar(255) NOT NULL, 
-- LastName nvarchar(255) NOT NULL, 
-- JobTitle nvarchar(50) NOT NULL 

--) 
----Returns a result set that lists all the employees who report to the 
----specific employee directly or indirectly.*/ 
--AS 
--BEGIN 
--WITH EMP_cte(EmployeeID, OrganizationNode, FirstName, LastName, JobTitle, RecursionLevel) -- CTE name and columns 
-- AS (
--  SELECT e.EmployeeID, e.ManagerID, p.FirstName, p.LastName, P.JobTitle, 0 -- Get the initial list of Employees for Manager n 
--  FROM HumanResources.Employee e 
--INNER JOIN Person.Person p 
--ON p.Employeeid = e.EmployeeID 
--  WHERE e.EmployeeID = @InEmpID 
--  UNION ALL 
--  SELECT e.EmployeeID, e.ManagerID, p.FirstName, p.LastName, P.JobTitle, RecursionLevel + 1 -- Join recursive member to anchor 
--  FROM HumanResources.Employee e 
--   INNER JOIN EMP_cte 
--   ON e.ORGANIZATIONNODE.GetAncestor(1) = EMP_cte.OrganizationNode 
--INNER JOIN Person.Person p 
--ON p.Employeeid= e.EmployeeID 
--  ) 
---- copy the required columns to the result of the function 
-- INSERT @retFindReports 
-- SELECT EmployeeID, FirstName, LastName, JobTitle, RecursionLevel 
-- FROM EMP_cte 
-- RETURN 
--END; 
--GO 

> 
Các vấn đề liên quan