更新表的外键

时间:2014-07-07 14:58:30

标签: sql sql-server sql-server-2012

我希望这是有道理的。

我有两张桌子。表2具有表1的id的外键。表1添加了基于创建日期的新数据。如何使用新id更新表2的外键。

Table 1:
╔═════════════════════════╗
║     id code createdDate ║
╠═════════════════════════╣
║     1  xxx  05/07/2013  ║
║     2  xyz  05/07/2013  ║
║     3  xxx  07/07/2014  ║
╚═════════════════════════╝

表2:

╔════════════════════════════════╗
║     id codeId  description     ║
╠════════════════════════════════╣
║     1   1      xxx description ║
║     2   2      xyz description ║
╚════════════════════════════════╝

我必须将Table2 codeId更新为3和1.出于历史目的,我无法删除Table1的旧条目。

我禁用了外键并创建了一个在子查询中以多列返回的查询。

UPDATE TABLE2 
SET    CODEID = (SELECT ID 
                 FROM   TABLE1 
                 WHERE  CODE = (SELECT T.CODE 
                                FROM   TABLE2 
                                       INNER JOIN (SELECT CODE, 
                                                          MAX(CREATEDDATE) AS 
                                                          maxDate 
                                                   FROM   TABLE1 
                                                   GROUP  BY CODE) tm 
                                               ON T.CODE = tm.CODE 
                                                  AND T.CREATEDDATE = tm.MAXDATE 
                               )) 

2 个答案:

答案 0 :(得分:0)

尝试这样的事情:

;WITH MAXT 
     AS (SELECT CODE, 
                MAX(CREATEDDATE) createdDate 
         FROM   TABLE1 
         GROUP  BY CODE), 
     MAXTOTAL 
     AS (SELECT T1.* 
         FROM   TABLE1 T1 
                INNER JOIN MAXT T2 
                        ON T1.CODE = T2.CODE 
                           AND T1.CREATEDDATE = T2.CREATEDDATE) 
UPDATE T2 
SET    codeid = T1.ID 
FROM   TABLE2 T2 
       INNER JOIN MAXTOTAL T1 
               ON T1.CODE = LEFT(T2.DESCRIPTION, 3) 

SELECT * 
FROM   TABLE2 

您可以在SQL Fiddle

上看到一个有效的示例

答案 1 :(得分:0)

如果我正确理解您的问题,您需要将Table2更新为较新版本或Table1记录的某些内容。在您的结构中,您只有Table2.codeId作为Table1的链接。因此,您需要一种映射表,告诉您Table1中的每条记录,这是与最新版本的相关记录:

SELECT t1.id,tmp.latestId
FROM Table1 t1
   JOIN (SELECT code,max(id) latestId
        FROM Table1
        GROUP BY code
        HAVING count(*)>1) tmp ON tmp.code=t1.code

这只会因为标识列而起作用。它也可以通过日期列来完成,这将需要在子查询上进行额外的连接。

现在您可以使用映射表来连接Table2。我认为这比使用Table1.codeSubstring(Table2.description)要好,因为使用唯一ID会更可靠。

WITH cte (codeId,lastestId)
AS (
SELECT t1.id,tmp.latestId
FROM Table1 t1
   JOIN (SELECT code,max(id) latestId
        FROM Table1
        GROUP BY code
        HAVING count(*)>1) tmp ON tmp.code=t1.code
)       
UPDATE t2 SET codeId=cte.lastestId
FROM cte
    JOIN Table2 t2 ON t2.codeId=cte.codeId