更新查询以获取没有唯一键的新记录?

时间:2012-03-09 16:09:07

标签: sql ms-access

我有一张会计交易表,我正在尝试将它们复制到一个新表中。我已经完成了复制,但我需要使用源表中的任何新事务更新副本。我遇到的问题是源数据来自一个报告,该报告链接许多不同的来源以创建这些交易,并且没有唯一的密钥。

如果我有一个唯一键,我会创建一个更新查询并从源表到复制表执行左连接,并且只要复制表中的键为空,就更新这些字段。

由于我没有唯一的密钥,我不知道如何实现这一点。有什么想法吗?

-----由于答案而编辑-----

SourceTable
Field1   Field2   Field3

CopiedTable
Field1   Field2   Field3

所以要用新记录更新CopiedTable我会这样做吗?

UPDATE CopiedTable SET 
       CopiedTable.Field1 = SourceTable.Field1,
       CopiedTable.Field2 = SourceTable.Field2,
       CopiedTable.Field3 = SourceTable.Field3
WHERE (SourceTable.Field1 <> CopiedTable.Field1 AND 
       SourceTable.Field2 <> CopiedTable.Field2 AND 
       SourceTable.Field3 <> CopiedTable.Field3)

1 个答案:

答案 0 :(得分:1)

如果不查看源表,目标表和查询,很难回答这个问题。

使用由不同表的所有唯一键字段组成的复合键。


编辑:

每个表都必须有一个主键。这是数据库的基本设计规则。我们假设您有两个源表A和B

Table A
-------
A_ID, DataField1, DataField2

Table B (lined to Table A through A_ID)
-------
B_ID, A_ID, DataField3, DataField4

现在你可以像这样创建表格

SELECT
    CLng(A.A_ID) AS A_ID, CLng(B.B_ID) AS B_ID,
    A.DataField1, A.DataField2, B.DataField3, B.DataField4
INTO
    C
FROM
    A INNER JOIN B ON A.A_ID = B.A_ID;

我会在A_ID中将B_IDC作为主键。

如果A_IDB_ID是自动编号,我们需要使用CLng进行操作,以便在C中创建常规数字字段。

如果稍后我们想用A和B的新数据重新填充C,我们可以

DELETE * FROM C;

INSERT INTO C
    (A_ID, B_ID, DataField1, DataField2, DataField3, DataField4)
SELECT
    A.A_ID, B.B_ID, A.DataField1, A.DataField2, B.DataField3, B.DataField4
FROM
    A INNER JOIN B ON A.A_ID = B.A_ID;

如果我们只想更新已更改的记录,我们需要将源与副本链接,另外,如果我们在WHERE子句中有更改,则测试

UPDATE
    C
    INNER JOIN (SELECT
                  A.A_ID, B.B_ID,
                  A.DataField1, A.DataField2, B.DataField3, B.DataField4
                FROM
                  A INNER JOIN B ON A.A_ID = B.A_ID) AS Src
      ON C.B_ID = Src.B_ID AND C.A_ID = Src.A_ID
SET
    C.DataField1 = Src.DataField1,
    C.DataField2 = Src.DataField2,
    C.DataField3 = Src.DataField3,
    C.DataField4 = Src.DataField4
WHERE
    C.DataField1<>Src.DataField1 OR
    C.DataField2<>Src.DataField2 OR
    C.DataField3<>Src.DataField3 OR
    C.DataField4<>Src.DataField4;

子选择Src可能是另一个存储的查询。