尝试排除一个月时出现字符串转换错误

时间:2018-09-17 09:23:12

标签: sql sql-server tsql date datetime

因此,我仍在学习SQL的来龙去脉,并且试图找出我做错了什么。

SELECT P.productid, P.productname, O.orderdate
FROM Production.Products AS P INNER JOIN
Sales.OrderDetails AS D ON P.productid = D.productid
INNER JOIN Sales.Orders AS O ON D.orderid = O.orderid
WHERE (O.orderdate NOT BETWEEN '2015-09-01' AND '2015-09-31');

它会产生以下错误:

  

从字符转换日期和/或时间时转换失败   字符串。

任何帮助,将不胜感激。

3 个答案:

答案 0 :(得分:2)

假设orderdate是一个日期/日期时间,您应该得到的错误是:

  

将varchar数据类型转换为datetime数据类型   值超出范围。

这是因为 9月有30天,而不是31天。更改为2018-09-30

或者更好,使用EOMONTH()函数:

SELECT EOMONTH('2019-02-01')
-- 2019-02-28
SELECT EOMONTH('2020-02-01')
-- 2020-02-29 because 2020 is a leap year

或更妙的是,不要使用BETWEEN

WHERE NOT (O.orderdate >= '2015-09-01' AND O.orderdate < '2015-10-01')

答案 1 :(得分:1)

DECLARE @Date DATE = '2018-09-01', @StartDate DATE, @EndDate DATE
SELECT @StartDate = DATEADD(MONTH, -1, DATEADD(DAY, 1, EOMONTH(@Date))), @EndDate = CAST(DATEADD(DAY, -(DAY(@Date)), @Date) AS DATE)

SELECT P.productid, P.productname, O.orderdate
FROM Production.Products AS P INNER JOIN
Sales.OrderDetails AS D ON P.productid = D.productid
INNER JOIN Sales.Orders AS O ON D.orderid = O.orderid
WHERE (O.orderdate NOT BETWEEN @StartDate AND @EndDate);

在第1行中声明3个日期变量@ Date,@ StartDate,@ EndDate并为@Date分配一个随机日期,例如“ 2018-09-01” 在第2行wrt到@Date,将开始和结束日期作为变量。 在第3行的where子句中添加这些日期

解决方案:通过这些步骤,您永远不会得到错误的日期开始和结束日期,因为在这里您仅提供一个随机日期,而作为回报,您将拥有2个包含Year + Month的开始和结束日期的日期。

答案 2 :(得分:0)

我强烈建议您避免将BETWEEN(和NOT BETWEEN)与日期/时间数据类型一起使用。亚伦·伯特兰德(Aaron Bertrand)的博客What do Between and the Devil have in Common?很好地解释了原因。

SELECT P.productid, P.productname, O.orderdate
FROM Production.Products P INNER JOIN
     Sales.OrderDetails D
     ON P.productid = D.productid INNER JOIN
     Sales.Orders O
     ON D.orderid = O.orderid
WHERE O.orderdate < '2015-09-01' OR
      O.orderdate >= '2015-10-01';