ms访问查询(ms访问冻结)

时间:2018-09-13 19:30:28

标签: sql ms-access

我有此报告,需要添加每个人的总计(红色圆圈) existing report

new report

我无法更改现有报告,因此我将数据从MS SQL导出到MS Access并在那里创建新报告。我让它只为一名员工工作,但是在查询多个员工时遇到了麻烦。

此查询提取数据用作输入:

SELECT [TIME].[RCD_NUM], [TIME].[EMP_ID], [TIME].[PPERIOD], [TIME].[PRUN], [TIME].[TDATE], [TIME].[PC], [TIME].[RATE], [TIME].[HOURS], [TIME].[AMOUNT], [TIME].[JOB_ID], [TIME].[UPDATED], [TIME].[UPDATED_BY], [TIME].[LOG_DATE], [TIME].[ORIGINAL_REC_NUM]
FROM [TIME]
WHERE ((([TIME].[EMP_ID])=376) And (([TIME].[TDATE])<=#12/31/2006# And ([TIME].[TDATE])>=#1/1/2006#) And (([TIME].[PC])<599));

此查询填充报告:

SELECT *
FROM TIME1
WHERE RCD_NUM = (SELECT Max(RCD_NUM) FROM [TIME1] UQ WHERE UQ.PPERIOD = [TIME1].PPERIOD AND UQ.PC = [TIME1].PC);

问题是,如果我从这样的第一个查询中删除EMP_ID

SELECT [TIME].[RCD_NUM], [TIME].[EMP_ID], [TIME].[PPERIOD], [TIME].[PRUN], [TIME].[TDATE], [TIME].[PC], [TIME].[RATE], [TIME].[HOURS], [TIME].[AMOUNT], [TIME].[JOB_ID], [TIME].[UPDATED], [TIME].[UPDATED_BY], [TIME].[LOG_DATE], [TIME].[ORIGINAL_REC_NUM]
FROM [TIME]
WHERE ((([TIME].[TDATE])<=#12/31/2006# And ([TIME].[TDATE])>=#1/1/2006#) And (([TIME].[PC])<599));

然后第二个查询不起作用,并且在运行该查询时,ms访问会冻结。

有什么帮助/想法吗?

1 个答案:

答案 0 :(得分:1)

注意事项:我不会假装知道问题的确切原因,但是即使原始SQL语句在Windows中完全有效,我也不得不在Access中反复重构查询以使它们正常工作。关于语法和逻辑。有时,为了避免Access中的错误,我不得不对一系列查询进行卷积。访问通常是愚蠢的,并且将完全按照给定的条件简单地(重新)执行查询和子查询,而无需优化。在其他时候,Access会尝试通过执行一些内部优化来合并查询,但有时会引入令人沮丧的错误。诸如名称更改或列重新排序之类的简单操作可能是功能正常的查询与崩溃或冻结Access的查询之间的区别。


首先考虑:

  • 是否可以将数据保留在SQL Server上并链接到Access中的结果(而不是将其导出/导入到Access中)?即使您需要或更喜欢使用Access创建实际的报表,也可以使用SQL Server的所有功能来查询数据-可能会减少错误,并且效率更高。
    • 常见的最佳实践是创建SQL Server存储过程,该存储过程返回Access中所需的数据。在Access中创建了传递查询来检索数据,但是所有数据操作都在服务器上执行。
  • 也许这只是一个性能问题,其中通过[EMP_ID]限制集合会选择一个小的子集,但是整个表足够大以“冻结” Access。
    • 在终止进程之前,您让Access冻结了多长时间?要耐心……像很多很多分钟(或几个小时)一样。早晨开始,午餐后检查。 :)最终可能会返回结果集。这并不意味着它是可以容忍的,或者没有其他解决方案,但是了解它最终是否返回数据可能很有用。
    • 有多少可能的记录?
    • 是否正确索引了导入的数据?将索引添加到所有关键字段以及WHERE子句中使用的那些字段。
    • 该数据库位于网络共享上还是本地?尝试将数据库复制到本地驱动器。

其他提示:

  • 在WHERE子句中尝试使用BETWEEN运算符获取日期。

通过在FROM子句而不是WHERE子句中执行联接,尝试重构“第二”查询。在执行此操作时,您可能还需要将子查询另存为命名查询(就像保存[TIME1]一样)。即使结果应相同,是否将查询保存或嵌入到另一个语句中也可以更改Access的行为(请参见警告)。

这是带有嵌入式聚合查询的版本。注意所有列引用如何与源一起限定。某些原始查询的列没有在列名前添加源别名。请记住警告,此类挑剔的细节可能会影响Access行为。

SELECT TIME1.*
FROM TIME1 INNER JOIN
  (SELECT UQ.PPERIOD, UQ.PC, Max(UQ.RCD_NUM) As Max_RCD_NUM
   FROM [TIME1] UQ
   GROUP BY UQ.PPERIOD, UQ.PC) As TIMEAGG
  ON (TIME1.PPERIOD = TIMEAGG.PPERIOD) And (TIME1.PC = TIMEAGG.PC)
    AND (TIME1.RCD_NUM = TIMEAGG.Max_RCD_NUM)