join – Access(Jet)SQL:TableB中的DateTime标记位于TableA中每
你说这个慢了.从代码的角度来看,它的可读性也较低.考虑到1到2之间同样令人满意的结果集,我会说1.至少你很明显你想要这样做.子查询通常不是很快(虽然通常是不可避免的),特别是在这种情况下,你在每个子系统中都会额外加入,这必然会使执行计划复杂化. 一句话,我看到你使用旧的ANSI-89连接语法.最好避免这种情况,使用更现代的连接语法,性能会相同或更好,并且它们不那么模糊或更容易阅读,更难以犯错误. FROM (FirstTable AS A INNER JOIN (select top 1 B1.XTStamp,A1.RecTStamp from SecondTable as B1 inner join FirstTable as A1 on B1.XTStamp <= A1.RecTStamp order by B1.XTStamp DESC) AS AbyB1 --MAX (time points before) 命名的东西 我认为你的东西被命名的方式充其量只是无益的,最糟糕的是神秘的. A,B,A1,B1等作为表别名我觉得可能会更好.另外,我认为字段名称不是很好,但我意识到你可能无法控制它.我将快速引用The Codeless Code关于命名事物的主题,并将其留在那……
“后续步骤”查询 我无法理解它是如何编写的,我不得不将它带到文本编辑器并进行一些样式更改以使其更具可读性.我知道Access的SQL编辑器超出了笨重,因此我通常在一个好的编辑器中编写我的查询,如Notepad或Sublime Text.我应用的一些风格变化使其更具可读性: > 4个空格缩进而不是2个空格 事实证明,这确实是一个非常复杂的查询.为了理解它,我必须从最里面的查询开始,你的ID数据集,我理解的与你的第一次加入相同.它返回您感兴趣的设备子集中最接近前/后时间戳的设备的ID和时间戳.因此,为什么不将ID称为ClosestTimestampID而不是ID. 您的Det联接仅使用一次: 其余的时间,它只加入ClosestTimestampID中已有的值.所以我们应该能够做到这一点: ) AS ClosestTimestampID INNER JOIN SecondTable AS TL1 ON ClosestTimestampID.BeforeXTStamp = TL1.XTStamp) INNER JOIN SecondTable AS TL2 ON ClosestTimestampID.AfterXTStamp = TL2.XTStamp WHERE ClosestTimestampID.XmitID IN (<limited subset S>) 也许不是一个巨大的性能提升,但我们可以做的任何事情来帮助可怜的Jet数据库优化器将有所帮助! 我不能动摇你用于插值的BeforeWeight和AfterWeight的计算/算法可以做得更好的感觉,但不幸的是我对这些并不是很好. 避免崩溃的一个建议(虽然根据您的应用程序而不理想)将是将嵌套子查询分解为自己的表并在需要时更新它们.我不确定您需要刷新源数据的频率,但如果不经常,您可能会考虑编写一些VBA代码来安排表和派生表的更新,并将最外层的查询留下来从那些表而不是原始来源.只是一个想法,就像我说的不理想,但鉴于工具,你可能没有选择. 一切都在一起: SELECT InGPS.XmitID,StrDateIso8601Msec(InGPS.RecTStamp) AS RecTStamp_ms,-- StrDateIso8601MSec is a VBA function returning a TEXT string in yyyy-mm-dd hh:nn:ss.lll format InGPS.ReceivID,InGPS.Before_Lat * InGPS.BeforeWeight + InGPS.After_Lat * InGPS.AfterWeight AS Xmit_Lat,InGPS.Before_Lon * InGPS.BeforeWeight + InGPS.After_Lon * InGPS.AfterWeight AS Xmit_Lon,InGPS.RecTStamp AS RecTStamp_basic FROM ( SELECT ClosestTimestampID.RecTStamp,ClosestTimestampID.XmitID,ClosestTimestampID.ReceivID,ClosestTimestampID.BeforeXTStamp,TL1.Latitude AS Before_Lat,TL1.Longitude AS Before_Lon,(1 - ((ClosestTimestampID.RecTStamp - ClosestTimestampID.BeforeXTStamp) / (ClosestTimestampID.AfterXTStamp - ClosestTimestampID.BeforeXTStamp))) AS BeforeWeight,ClosestTimestampID.AfterXTStamp,TL2.Latitude AS After_Lat,TL2.Longitude AS After_Lon,( (ClosestTimestampID.RecTStamp - ClosestTimestampID.BeforeXTStamp) / (ClosestTimestampID.AfterXTStamp - ClosestTimestampID.BeforeXTStamp)) AS AfterWeight FROM ((( SELECT A.RecTStamp,MAX(SWITCH(B.XTStamp <= A.RecTStamp,Null)) AS BeforeXTStamp,MIN(SWITCH(B.XTStamp > A.RecTStamp,Null)) AS AfterXTStamp FROM FirstTable AS A INNER JOIN SecondTable AS B ON (A.RecTStamp <> B.XTStamp OR A.RecTStamp = B.XTStamp) WHERE A.XmitID IN (<limited subset S>) GROUP BY A.RecTStamp,XmitID ) AS ClosestTimestampID INNER JOIN FirstTable AS Det ON (Det.XmitID = ClosestTimestampID.XmitID) AND (Det.ReceivID = ClosestTimestampID.ReceivID) AND (Det.RecTStamp = ClosestTimestampID.RecTStamp)) INNER JOIN SecondTable AS TL1 ON ClosestTimestampID.BeforeXTStamp = TL1.XTStamp) INNER JOIN SecondTable AS TL2 ON ClosestTimestampID.AfterXTStamp = TL2.XTStamp WHERE Det.XmitID IN (<limited subset S>) ) AS InGPS INNER JOIN ReceiverDetails AS RD ON (InGPS.ReceivID = RD.ReceivID) AND (InGPS.RecTStamp BETWEEN <valid parameters from another table>) ORDER BY StrDateIso8601Msec(InGPS.RecTStamp),InGPS.ReceivID; (编辑:晋中站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |