因此,我仍在学习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');
它会产生以下错误:
从字符转换日期和/或时间时转换失败 字符串。
任何帮助,将不胜感激。
答案 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';