Access 2007:查询两个短日期值之间的 DateTime 字段
Posted
技术标签:
【中文标题】Access 2007:查询两个短日期值之间的 DateTime 字段【英文标题】:Access 2007: Querying for DateTime field between two Short Date values 【发布时间】:2009-10-07 14:41:26 【问题描述】:我有一个包含两个文本框供用户输入的表单。两个文本框的属性格式都设置为“短日期”。一个是“开始日期”,另一个是“结束日期”。我还有几个表,每个表都有一个 DateTime 字段(“studystartdatetime”)。我希望能够查询这些表,但将结果限制为 DateTime 字段介于输入日期(含)之间的行。目前,条件是:
WHERE s.studystartdatetime BETWEEN forms!frmMain!txtstartdate AND forms!frmmain!txtenddate
但是,这不会返回在指定的结束日期发生的行。
我已经尝试了 CDate、Format 和 DateValue 的所有组合,我可以想到在其中包装一个或所有这些字段,但我总是收到相同的神秘错误:
表达式输入错误,或者太复杂而无法计算。例如,一个数值表达式可能包含太多复杂的元素。尝试通过将部分表达式分配给变量来简化表达式。
我尝试过的一些条件示例:
WHERE CDate(Format(s.studystartdatetime, "yyyy/mm/dd")) BETWEEN forms!frmMain!txtstartdate AND forms!frmmain!txtenddate
WHERE DateValue(Format(s.studystartdatetime, "yyyy/mm/dd")) BETWEEN forms!frmMain!txtstartdate AND forms!frmmain!txtenddate
WHERE CDate(Format(s.studystartdatetime, "yyyy/mm/dd")) BETWEEN CDate(Format(forms!frmMain!txtstartdate, "yyyy/mm/dd")) AND CDate(Format(forms!frmmain!txtenddate, "yyyy/mm/dd"))
WHERE DateValue(Format(s.studystartdatetime, "yyyy/mm/dd")) BETWEEN CDate(Format(forms!frmMain!txtstartdate, "yyyy/mm/dd")) AND CDate(Format(forms!frmmain!txtenddate, "yyyy/mm/dd"))
WHERE DateValue(Format(s.studystartdatetime, "Short Date")) BETWEEN forms!frmMain!txtstartdate AND forms!frmmain!txtenddate
等等
对此的任何意见将不胜感激:)
【问题讨论】:
【参考方案1】:发生的情况是,您的短日期输入在用户输入的当天开始时的午夜生成日期时间值。因此,范围 2009-1-1 到 2009-1-10(或您系统上使用的任何短日期格式)正在搜索从 1 月 1 日开始到开始的事件1 月 10 日,不包括 1 月 10 日晚些时候发生的事件。
要更正,请将用户输入搜索的结束日期加 1。这将从 1 月 1 日开始到 1 月 11 日开始进行搜索,包括 1 月 10 日的所有事件。
最后,发生在恰好 1 月 11 日午夜的事件可以通过这种方式进入您的结果,因此您应该使用
而不是使用 BETWEENstudystartdatetime >= forms!frmMain!txtStartDate AND studystartdatetime
【讨论】:
我曾考虑过这样做,但由于某种原因只是假设不可能添加到这样的日期值。无论如何,谢谢!【参考方案2】:Larry 的答案对你来说是正确的答案,但让我引出这里提出的一些问题。
您需要区分日期格式和日期存储。在 Jet/ACE 数据库引擎(Access 的默认数据库引擎)中,日期以整数形式存储日期,以小数部分存储时间。这就是为什么您可以将数字(或小数)添加到日期并获得正确结果的原因,因为日期的基础表示的整数部分表示自 1899 年 12 月 30 日以来的天数(它不是 Dec. . 31 日很复杂——有人在计算闰年时搞砸了,因此编写了一大堆程序时都错误地假设了 1899 年 12 月 31 日实际上是什么时候)。
“短日期”是一种日期格式,即标准 m/d/yy(或 m/d/yyyy,取决于您在 Windows 和 Access 中的本地设置)。它与存储在表中的实际基础日期值无关,但如果您使用格式化的结果,它会产生巨大的影响。例如,Format(Date(), "m/d/yyyy") 返回一个字符串,而不是日期值。它是一个可以隐式强制转换为日期值的字符串,并且经常依赖于透明地发生。但是你还是要明白 Format() 函数返回的是一个字符串,而且这个字符串并不总是被当作一个日期来处理。
Jet/ACE SQL 期望格式化日期以美国顺序传递,即违反直觉的 m/d/yyyy,而不是更符合逻辑的 d/m/yyyy,或者更好的是 ISO 标准 yyyy/米/天。因此,每当您使用为 Windows 设置的非美国语言环境运行您的应用程序时,您需要明确说明您的日期。这意味着将日期转换为明确的格式(d/mmm/yyyy 有效,因为它以数字指定日期,以字母指定月份),或者使用 DateSerial() 函数处理所有日期。这适用于 WHERE 子句中的日期标准,或 SELECT 语句中进行日期计算的任何地方——将日期以明确的格式或使用 DateSerial() 传递到函数中,您将避免此问题。
【讨论】:
以上是关于Access 2007:查询两个短日期值之间的 DateTime 字段的主要内容,如果未能解决你的问题,请参考以下文章
Access 2007:“SELECT COUNT(DISTINCT ......”)