2012-07-11 90 views
5

我刚刚意识到我一直在捕捉表格中一列的错误数据。但是,我已经解决了这个问题,但迄今为止我所捕获的数据仍然不正确。如何使用其他表格数据更新一列数据TSQL

让我们的名字我的表TableIWantToCorrectTableWithIDs

TableIWantToCorrect,我有一个外键TableWithIDs。这是不正确的。

我可以通过比较TableIWantToCorrect中列的子字符串与TableWithIDs中的列来更正数据。

所以目前,我有

TableIWantToCorrect

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

TableWithIDs

CompareName id 
abc   1 
def   2 
ghi   3 

所以我想更新TableIWantToCorrect有正确的ForeignKey的值时,在该子名称等于子字符串在比较名称。子串的位置总是相同的,所以我可以使用Substring方法。

我尝试:

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

结果:

子查询返回多个值。当 子查询遵循=,!=,<,< =,>,> =或当子查询用作 表达式时,这是不允许的。该语句已终止。

我知道我做了些傻事。我在这里做错了什么?

+1

您的在线查询做到这一点,因此返回多于一行的问题。运行此查询找出哪些是重复的'选择CompareName,COUNT(1) \t FROM TableWithIDs GROUP BY CompareName HAVING COUNT(1)> 1 \t ' – Chandu 2012-07-11 14:14:19

+0

你还,如果您更改子查询得到的错误使用'SELECT DISTINCT id'?如果是这样,则有多个可能的匹配,并且使用哪一个不明确。 – 2012-07-11 14:43:19

+0

[UPDATE from SELECT using SQL Server]可能的重复(http://stackoverflow.com/questions/2334712/update-from-select-using-sql-server) – 2014-06-05 16:55:45

回答

13

这个错误是因为你的子查询的UPDATE返回多条记录。为了解决这个问题,你可以使用一个JOINUPDATE

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

我知道这是一个特定的SQL Server问题,但是如果您希望执行此操作的MySQL等效项,请尝试在此处:http://stackoverflow.com/a/11709090/403264 – JonRed 2013-10-22 01:12:04

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

您可以随时告诉谁在Oracle中工作,他们从不使用连接命令。 ;) – Limey 2012-07-11 14:17:35

+1

不幸的是我在Oracle和Sql服务器之间摇摆,所以有时候我会感到困惑。尽管如此,他们产生相同的结果,但仍然加入应该是首选.http://stackoverflow.com/questions/1018822/inner-join-on-vs-where-clause – praveen 2012-07-11 14:31:38

+1

我在Oracle 10年,我曾经讨厌加入声明!出于某种原因,我总是发现它很难阅读,但在SQL服务器经过多年后,我看到了我的方式的错误,并始终使用连接。 – Limey 2012-07-11 14:51:29

-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 

> 
相关问题