使用带有NOT EXISTS的INNER JOIN访问INSERT语句会产生错误的结果

时间:2011-06-27 19:04:26

标签: sql ms-access

我有一个Access .mdb数据库。有两个表具有相同的结构:价格和tmpPrices。每个表有三列:[截至日期标准](日期/时间),价格(双),CUSIP(文本,255个字符)。 tmpPrices包含要添加到价格的新记录。我有两个SQL查询来更新来自tmpPrices的价格,一个使用WHERE连接,另一个使用INNER JOIN。

以下版本A正常运行:

INSERT INTO [Prices] SELECT * FROM [tmpPrices] WHERE NOT EXISTS 
(SELECT * from [Prices]
  WHERE ([Prices].[As of date std] = [tmpPrices].[As of date std])
  AND ([Prices].CUSIP = [tmpPrices].CUSIP));

而这个版本B不起作用:

INSERT INTO [Prices] SELECT * FROM [tmpPrices] WHERE NOT EXISTS
(SELECT  [Prices].* FROM [Prices] INNER JOIN [tmpPrices] ON 
   ([Prices].[As of Date std] = [tmpPrices].[As of Date std]) 
   AND ([Prices].CUSIP = [tmpPrices].CUSIP));

两个子查询都给出了相同的结果:来自tmpPrices的记录子集已经存在于Price中。

使用版本A并不重要我是不是必须更新其他表而另一个表需要大约45分钟才能使用版本A进行更新但只有一小部分使用版本B并且它似乎正常工作。所以我想了解这里发生了什么。

3 个答案:

答案 0 :(得分:3)

正如@devsh建议的那样,LEFT JOIN绝对是可行的方法,但您不需要使用子查询。我在Access的查询设计器中构建了它,它可以在Access 2003中使用您描述的表。我确实重命名[截止日期标准]以消除空格。

INSERT INTO Prices ( As_of_Date_std, Price, CUSIP)
SELECT t.As_of_Date_std, t.Price, t.CUSIP
FROM
    tmpPrices AS t
    LEFT JOIN Prices AS p
    ON (t.As_of_Date_std = p.As_of_Date_std) AND (t.CUSIP = p.CUSIP)
WHERE (((p.As_of_Date_std) Is Null));

答案 1 :(得分:1)

第二个查询不起作用,因为查询的选择部分(您尝试从中插入)与包含的子查询之间没有链接。如果您确实想要使用该格式进行插入,可以执行以下操作:

INSERT INTO [Prices]
SELECT [As of Date], Price, CUSIP
FROM 
(SELECT tmpPrices.[As of Date std], tmpPrices.[Price], tmpPrices.[CUSIP]
FROM tmpPrices LEFT JOIN Prices ON
([Prices].[As of date std] = [tmpPrices].[As of date std]) AND ([Prices].CUSIP = [tmpPrices].CUSIP)) WHERE Prices.[As of date std] is null)

答案 2 :(得分:0)

A花了这么长时间,因为它基本上对价格中的每条记录进行了tmpPrices的全表扫描,因为在子查询中没有定义实际的连接。

让我们看看我们是否可以为您提供快速查询,为您提供所需的信息。

tmpPrices需要一个自动编号字段才能工作,我建议将它作为tmpPrices的pk。另外一个基于3个其他字段的唯一键,以防止tmpPrices中的重复(非常确定您可以在Access中执行此操作)。

INSERT INTO [Prices] ([As of Date std],[Price],[CUSIP])
SELECT [As of Date std],[Price],[CUSIP] from tmpPrices where autoNumberID not in(
  SELECT autonumberID
  FROM tmpPrices 
  innerJoin prices on [Prices].[As of Date std] = [tmpPrices].[As of Date std] 
   AND [Prices].CUSIP = [tmpPrices].CUSIP
) query1

如果每次用此更新价格时清除tmpPrices中的任何记录,它也会有助于保持速度。