我有一个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并且它似乎正常工作。所以我想了解这里发生了什么。
答案 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中的任何记录,它也会有助于保持速度。