我继承了一个包含<tab>
和Start_Date
列的End_Date
数据类型的T-SQL表。我需要选择特定日期的所有记录,其开始日期是在该日期之前,但在该日期之后有结束日期。
另一个问题是有些人仍然是最新的,没有nvarchar
。遗憾的是,我不能只将列的数据类型转换为日期。我试图在VBA中写这个,因为
例如:
end_date
如果我选择的日期是2015年8月15日,我的返回数据应为
Name Start_Date End_Date
Joe 12/1/2014 6/15/2016
Bob 8/28/2013 6/5/2014
Jon 1/27/2015 12/18/2015
Tim 8/28/2013
我已尝试过以下查询,但他们会返回Name Start_Date End_Date
Joe 12/1/2014 6/15/2016
Jon 1/27/2015 12/18/2015
Tim 8/28/2013
Run-time error -2147217900 (80040e14) Automation error
编辑: 我使用以下代码构造我的查询:
SELECT NAME
FROM INFORMATION
WHERE CONVERT(datetime, START_DATE, 101) >= '12/1/2015'
AND CONVERT(datetime, END_DATE, 101) <= '12/31/2015'
SELECT NAME
FROM INFORMATION
WHERE START_DATE >= '12/1/2015'
更新2:
我将For intYear = Year(Now()) To 2012 Step -1
For intMonth = 12 To 1 Step -1
FirstDayOfMonth = DateSerial(intYear, intMonth, 1)
LastDayOfMonth = DateSerial(intYear, intMonth + 1, 0)
SQL = "SELECT NAME FROM dbo.INFORMATION " & _
"WHERE CONVERT(DATETIME, START_DATE, 101) <= " & FirstDayOfMonth & " AND " & _
"CASE END_DATE WHEN '' THEN GETDATE() " & _
"ELSE CONVERT(DATETIME, END_DATE, 101) END >= " & LastDayOfMonth
Debug.Print SQL
'Output:
'SELECT NAME FROM dbo.INFORMATION WHERE CONVERT(DATETIME, START_DATE, 101)
'<= 12/1/2016 AND CASE END_DATE WHEN '' THEN GETDATE() ELSE
'CONVERT(DATETIME, END_DATE, 101) END >= 12/31/2016
Set rs = cn.Execute(SQL)
Next intMonth
Next intYear
设置为文字查询,而不是动态生成它并放入错误捕获(我很久以前就应该这样做)。我认为在日期周围加上单引号会使它成为字符串而不是日期,但我尝试了两种方式。
SQL
使用和不使用单引号SSMS的实际SQL错误是:
SQL = "SELECT EMPLOYEE_NAME FROM dbo.INFORMATION " & _
"WHERE CONVERT(DATETIME, START_DATE, 101) <= 12/01/2016 " & _
"AND CASE END_DATE " & _
"WHEN '' THEN GETDATE() " & _
"ELSE CONVERT(DATETIME, END_DATE, 101) " & _
"END >= 12/31/2016"
查看表格中的数据,我可以看到有些日期是NULL,有些是空白,有些是mm / dd / yy(甚至是m / d / yy)。我希望SQL能够完成所有繁重的工作,但是现在我想确定Msg 241, Level 16, State 1, Line 4
Conversion failed when converting date and/or time from character string.
是否会更难对付它并在Excel中处理它或者让我的老板,他的同事和我的祖父与我联系#39;固定&#39;桌子。
答案 0 :(得分:2)
您需要切换&gt; =和&lt; =。现在,您正在寻找在目标日期之后的开始日期和结束日期之前的人。但我认为这只是你的例子中的一个错字。
但你走在正确的轨道上。如果你想在VBA中这样做,我会警告不要在VBA中做任何逻辑。在SQL中进行所有过滤,只需使用VBA来调用SQL。另外,不要忘记您可以将Excel直接连接到SQL作为数据源并跳过VBA。
无论如何,您的SQL查询应该如下所示:
SELECT Name
FROM dbo.INFORMATION
WHERE CONVERT(DATETIME, Start_Date, 101) <= @targetdate
AND CONVERT(DATETIME, End_Date, 101) >= @targetdate
但是你有一个没有结束日期的人的情况。让我们解决它所以它都适合一个查询。
SELECT Name
FROM dbo.INFORMATION
WHERE CONVERT(DATETIME, Start_Date, 101) <= @targetdate
AND CASE End_Date
WHEN '' THEN GETDATE()
ELSE CONVERT(DATETIME, End_Date, 101)
END >= @targetdate
如果他们有结束日期,我们会使用他们的结束日期,如果他们没有,我们现在就使用它们。如果您的目标日期可能在将来,那么您可以使用任意大的日期。
最后一项是使用BETWEEN:
使其更具可读性SELECT Name
FROM dbo.INFORMATION
WHERE @targetdate BETWEEN CONVERT(DATETIME, Start_Date, 101)
AND CASE End_Date
WHEN '' THEN GETDATE()
ELSE CONVERT(DATETIME, End_Date, 101)
END