SQL 日期比较设置错误导致 SQL 结果不准确

Posted

技术标签:

【中文标题】SQL 日期比较设置错误导致 SQL 结果不准确【英文标题】:The SQL result is inaccurate because of wrong SQL date comparison setting 【发布时间】:2016-07-25 05:57:58 【问题描述】:

我在 excel-VBA 中使用 ADO 在 excel 中运行 SQL。结果显示在 Excel 工作表上。

工作表 2014,2015,2016,2017 中有一个名为 Date 的字段

数据示例:2/1/2014,7/1/2014,23/10/2014

此字段数据类型为日/月/年。日期由 =DATE(cell1,cell2,cell3) -year,month ,day 组合而成。表格中的日期应该都是纯日期,因为我结合了 3 个单元格(年、月、日)到1个字段(日期)

'Dim two date variables 

Dim fromDate As Date
Dim toDate As Date

'Dim 4 integer variables   

Dim fromyear As Integer
Dim toyear As Integer
Dim frommonth As Integer
Dim ToMonth As Integer

'add combobox value
With FromYearC
.AddItem 2014
.AddItem 2015
.AddItem 2016
.AddItem 2017
End With

'add combobox value 
With FromMonthC
.AddItem 1
.AddItem 2
.AddItem 3
.AddItem 4
.AddItem 5
.AddItem 6
.AddItem 7
.AddItem 8
.AddItem 9
.AddItem 10
.AddItem 11
.AddItem 12
End With

'Store combo box value into these 4 integer variables 

fromyear = FromYearC.Value
frommonth = FromMonthC.Value
toyear = ToYearC.Value
ToMonth = ToMonthC.Value

'Now i want to combine these variables and store into fromDate and toDate
fromDate = DateSerial(fromyear, frommonth, 1)
toDate = DateSerial(toyear, ToMonth + 1, 1)

'it is still wrong , no matter orginal date format or new date format"dd/mm/yyyy"
  fromDate = Format(fromDate, "dd/mm/yyyy")
    toDate = Format(toDate, "dd/mm/yyyy")

VBA 用户界面: 现在我想设置 fromdate 和 todate 之间的日期范围(包括)

我将 SQL 引用构建到: How to combine 3 VBA variable into date datatype in VBA

 ' This is the new SQL string

WHERE date >= #" & fromdate & "# AND date<#" & toDate & "#"

问题:

现在 SQL 结果完全错误(仍然有输出)。我猜 SQL where 子句有问题。由于 SQL 本来是对的,所以 SQL 在 where-date 选择子句上就出错了。

或者我尝试使用 where-between 子句。这仍然是错误的。

date between  #" & fromDate & "#  and  #" & toDate & "#

完整的 SQL 在这里,但我认为它太长了

    SELECT  officer ,NULL, SUM(IIF( isnumeric(mkt) = true and Survey='CPI' and Activity='FI' and Outcome= 'C', Totalmin, 0 )/468) , SUM(IIF( isnumeric(Non) = true and Survey='CPI' and Activity='FI' and Outcome= 'C', Totalmin, 0 )/468) ,NULL ,NULL , IIF(ISNULL(sum(mkt)),0,sum(mkt)),Sum(Non),sum(ICP),(sum(mkt)+Sum(Non)+sum(ICP) )  ,NULL,NULL,NULL,count(IIF( Survey='CPI' and Activity='FI' ,Totalmin, NULL )),NULL,count(IIF(  Survey='CPI' and Activity='FI' and  (Outcome ='C' OR Outcome='D'OR Outcome='O') , Totalmin, NULL )),NULL,SUM(IIF( Survey='CPI' and Activity='FI' ,Totalmin, 0 )),NULL,SUM(IIF( Survey='CPI' and Activity='FI' and (Outcome ='C' OR Outcome='D') ,Totalmin, 0 )) From  (select officer ,rank ,year ,month ,day , survey ,activity ,outcome ,mkt,non,totalmin,ICP ,date from [2014$] UNION ALL  select officer ,rank ,year ,month ,day , survey ,activity ,outcome ,mkt,non,totalmin,ICP ,date from [2015$]  UNION ALL  select officer ,rank ,year ,month ,day , survey ,activity ,outcome ,mkt,non,totalmin,ICP ,date from 
[2016$] UNION ALL  select officer ,rank ,year ,month ,day , survey ,activity ,outcome ,mkt,non,totalmin,ICP ,date from [2017$])as table3 where officer is not null and officer <> '' and officer <> ' '  and  date >= #" & fromDate & "# AND date<#" & toDate & "#" group by officer

更新

我尝试使用硬编码

 and date >= #1-3-2016# AND date<#31-3-2016#

测试 SQL 。

它像原来的 SQL 一样失败。它可以输出结果,但结果是错误的。

我猜它与 UNION ALL 有关吗? 当我加入所有 4 个表记录成为一个大表时。

更新 2

我相信它与 UNION ALL 无关。 由于excel列日期组合在3个单元格中 - 年,月,日,我再次复制并粘贴该值。SQL结果发生了变化。但是,结果仍然不正确。

然后我尝试使用硬代码进行测试。 例如,我尝试选择 2016 年 3 月的记录。 使用这个 where 子句:

and month=3 and year=2016

没关系。

然后我尝试在下面使用这个 where 语句。这不行。

date >= #2016-03-01# AND date<#2016-04-01#

那么我认为这应该是excel或VBA中的日期数据类型问题。

然后,我尝试在下面进行这些测试:

对于 Excel,原始数据类型是日期。我更改为字符串、数字、通用...不行

样本日期:2016 年 6 月 1 日 字符串示例:42375 数值样本:42375.00

对于 VBA,我尝试交换月份和日期。 --> #2016-01-03# 还是不行

【问题讨论】:

您的地区日期设置是什么? dd/mm/yyyy 或 mm/dd/yyyy? @Jules excel 中的日期是 dd/mm/yyyy 。我将 VBA 日期变量更改为 dd/mm/yyyy。但是,它仍然是错误的。 fromDate = Format(fromDate, "dd/mm/yyyy") toDate = Format(toDate, "dd/mm/yyyy") 你为什么使用date作为列名? @KyloRen 因为我必须将 4 个表记录组合成一个大表,我可以让用户从特定的日期时间段中进行选择,如一个月、一年等。 你不应该使用它作为名字,它可能会导致问题。 【参考方案1】:

您需要为 fromDate 和 toDate 日期创建字符串变量,并将它们传递给 WHERE 子句。我建议你使用 ISO 日期格式。除此之外,为了避免列名 date 出现问题,让我们尝试将 date 列括在方括号中(对联合表也这样做),如下所示:

  fromDateStr = Format(fromDate, "yyyy-mm-dd")
    toDateStr = Format(toDate, "yyyy-mm-dd")

"WHERE [date] >= #" & fromDateStr & "# AND [date]<#" & toDateStr & "#"

顺便说一句,当 toMonth 是 12 月时,这个表达式 DateSerial(toyear, ToMonth + 1, 1) 会发生什么?你不应该使用DateAdd函数吗?

toDate = DateAdd("m", 1, DateSerial(toyear, ToMonth, 1))

【讨论】:

附加信息,获取当月的最后一天 DateAdd("d",-1,DateAdd("m", 1, "1 jan 2016")) 或者使用 Format(fromDate, "dd mmm yyyy") 有没有可能是日期是对的,但是当你在 Excel 的屏幕上显示它时,日期格式是错误的? @Monchhichi 尝试对日期范围进行硬编码,看看它是否返回预期结果。 @cha 我试过and date &gt;= #1-3-2016# AND date&lt;#31-3-2016# 已经错了。我不知道是什么问题

以上是关于SQL 日期比较设置错误导致 SQL 结果不准确的主要内容,如果未能解决你的问题,请参考以下文章

在 Oracle SQL 中比较日期

如果仅按日和月将两个日期与 Oracle SQL 进行比较

Sql出错:日期的语法错误 查询数据的时候发现错误,请检查您的查询代码是不是正确。

SQL 报告生成器错误:未为“公共函数日(日期值作为日期)作为整数”的参数“日期值”指定参数

如何比较日期(年、月)和日期(日、月、年)

日期比较返回异常结果 - SQL Oracle