【问题标题】:Why is my date criteria filtering incorrectly in a MsysObjects query using DCount?为什么我的日期条件在使用 DCount 的 MsysObjects 查询中过滤不正确?
【发布时间】:2019-08-16 18:59:36
【问题描述】:

我有一个 Access 数据库,其中包含约 500 个表,并且所有表中总共有约 16,000 行。我想计算“datecreated”字段在 2019 年 1 月 1 日之前的行数。

我试图通过查询 MsysObjects 并使用按日期过滤的条件为每个表执行 DCount 来做到这一点。

假设我在内容如下的数据集上执行此操作:

  • table1:总共 10 行,2019 年 1 月 1 日之前的 5 行

  • table2:总共 10 行,2019 年 1 月 1 日之前的 9 行

  • table3:共 10 行,2019 年 1 月 1 日之前为 0

创建日期字段

我抽查了 500 张桌子中的一些。 “创建日期”字段是数据类型:日期/时间。格式为 yyyymmdd。

我创建了一个搜索,可以在其中按表获取所有行的计数,并且可以按各个字段过滤该搜索。但是,当我尝试按 datecreated 字段进行过滤时,我得到了奇怪的结果。它没有按照我期望的方式过滤。

1。基线查询(无条件):

(效果很好!)

SELECT MsysObjects.Name, DCount("*",[Name]) AS RecordTotal
FROM MsysObjects
WHERE (((Left$([Name],1))<>"~") AND ((Left$([Name],4))<>"Msys") AND ((MsysObjects.Type)=1))
ORDER BY MsysObjects.Name;

结果:

(结果如预期)

命名记录总数

table1 10

table2 10

table3 10

2。将条件添加到 DCount 的查询(创建日期
SELECT MsysObjects.Name, DCount("*",[Name],"[datecreated]<" & #01/01/2019#) AS RecordTotal
FROM MsysObjects
WHERE (((Left$([Name],1))<>"~") AND ((Left$([Name],4))<>"Msys") AND ((MsysObjects.Type)=1))
ORDER BY MsysObjects.Name;

预期结果:

命名记录总数

table1 5

表2 9

table3 0

实际结果:

命名记录总数

table1 0

table2 0

table3 0

3。在 DCount 中添加了不同格式条件的查询(datecreated
SELECT MsysObjects.Name, DCount("*",[Name],"[datecreated]<" & #20190101#) AS RecordTotal
FROM MsysObjects
WHERE (((Left$([Name],1))<>"~") AND ((Left$([Name],4))<>"Msys") AND ((MsysObjects.Type)=1))
ORDER BY MsysObjects.Name;

预期结果:

命名记录总数

table1 5

表2 9

table3 0

实际结果:

"查询表达式 DCount("*",[Name],"[datecreated]

4。向 DCount 添加了带有奇怪标准的查询(创建日期 > 01/01/9999):

SELECT MsysObjects.Name, DCount("*",[Name],"[datecreated]>" & #01/01/9999#) AS RecordTotal
FROM MsysObjects
WHERE (((Left$([Name],1))<>"~") AND ((Left$([Name],4))<>"Msys") AND ((MsysObjects.Type)=1))
ORDER BY MsysObjects.Name;

预期结果:

命名记录总数

table1 0

table2 0

table3 0

实际结果:

命名记录总数

table1 10

table2 10

table3 10

【问题讨论】:

  • 什么是 DBMS?如果这是用于 Microsoft Access,请删除 access 标记并将其更改为 ms-access。当您添加有关 pos up 的标签信息时,您应该阅读这些信息。 access 上的信息清楚地写着“不要将此标签用于 Microsoft Access”!
  • @stickybit 完成。
  • 为什么Access数据库中有近500个表?这更像是一个数据库设计问题,而不是 SQL 问题。如果表的结构相同,并带有后缀以区分,请考虑将所有表迁移到 one 表并避免使用MSys 表。访问表没有行限制。
  • @Parfait - 不错,建议很好。这将是另一天的任务,届时我们可能会完全从访问中删除数据库。这是一个组织数据库,我最近才参与其中。

标签: sql ms-access


【解决方案1】:

这最终奏效了:

SELECT MsysObjects.Name, DCount("*",[Name],"datecreated IS NOT NULL AND datecreated > #01-01-2019#") AS RecordTotal
FROM MsysObjects
WHERE (((Left$([Name],1))<>"~") AND ((Left$([Name],4))<>"Msys") AND ((MsysObjects.Type)=1))
ORDER BY MsysObjects.Name;

【讨论】:

  • 这是我在@computerversteher 解释更完整的答案之前找到的解决方案。我会把它留在这里供后代使用。
【解决方案2】:

您会得到错误的结果,因为您将条件连接起来,将日期转换为字符串。 例如

DCount("*",[Name],"[datecreated]<" & #01/01/2019#)

得到

DCount("*",[Name],"[datecreated]<01/01/2019")

/slash 是除法运算符: 1 除以 1 除以 2019 ~ 0.0049529

结果标准:

DCount("*",[Name],"[datecreated]<0.0049529

这解释了零结果,因为日期存储为整数值,其中 1899-12-30 由值 0 (tryDebug.Print CLng(#1899-12-30#)) 表示,1899-12-31 之后的一天是 1,而前一天是1899-12-29 是-1。您的所有日期都在那之后 (>1)。

DCount("*",[Name],"[datecreated]>" & #01/01/9999#)

得到 1 除以 1 除以 9999 ~ 0.0001

DCount("*",[Name],"[datecreated]>0.0001")

由于您的日期大于 1899 年 12 月 30 日,因此所有日期都算在内。

结论:如果您始终将日期标准与#-strings 连接起来,并使用美国格式 (mm/dd/yyyy) 或 ISO-Format(yyyy-mm-dd)。

DCount("*",[Name],"[datecreated]<#" & "01/01/2019" & "#")

或将它们转换为数字:

DCount("*",[Name],"[datecreated]<" & CLng(#01/01/2019#))

如果您有日期时间(时间 00:00:00),请转换为 Double,因为时间是一天中的一部分。

【讨论】:

  • relizt's 自己的答案显示了如何包含日期值。
  • 谢谢,这非常有帮助。尽管我能够找到有效的解决方案,但我不知道它为什么有效。您的回答解释并为我提供了从那里扩展的信息。谢谢!
猜你喜欢
  • 1970-01-01
  • 2021-11-12
  • 1970-01-01
  • 1970-01-01
  • 2019-11-24
  • 1970-01-01
  • 2019-01-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多