sql 服务器中的 Between 子句
Between clause in sql server
我正在尝试根据输入的开始和结束范围查找提交的数据。
假设我今天提交了数据,6 月 30 日
当我给出开始日期 6 月 1 日和结束日期 6 月 30 日的范围时,我没有得到今天提交的数据。当我给出开始日期 6 月 1 日和结束日期 7 月 1 日时,我得到了今天提交的数据。如何在 where 子句中也包含开始和结束日期?
AS
BEGIN
@Year navchar(200) = null
@Rtype navchar(200) = = null
SELECT *
FROM ProjectDetails
where SubmittedDate Between @Year and @Rtype
END
- --Convert The Date And check The Result Output
DECLARE
@Year NVARCHAR(200) = null,
@Rtype NVARCHAR(200) = null
SELECT *
FROM ProjectDetails
WHERE CONVERT(NVARCHAR, SubmittedDate,111) >= CONVERT(NVARCHAR,@Year,111) AND CONVERT(NVARCHAR,
SubmittedDate,111)<= CONVERT(NVARCHAR,@Rtype,111)
这是因为您误解了日期的工作原理。您将日期作为字符串传递和使用的事实进一步证明了这一点
首先,sql 服务器内部的日期表示为自某个日期(1900 年 1 月 1 日午夜)以来的天数
这意味着 1900 年 1 月 2 日在 sql 服务器内部表示为 1.0。 1900 年 1 月 2 日的 1800 小时日期在内部表示为 1.75 - 因为自第一个午夜以来已经有 1.75 天。下午 6 点是一天 24 小时的四分之三,因此内部表示中的 .75 部分
到目前为止和我在一起吗?
是小数点部分打败了你的逻辑
让我们看一个例子
假设您想要 1900 年 1 月 1 日到 1900 年 1 月 10 日之间的记录,所以实际上,您想要的记录在 1900 年 1 月 10 日 23:59:59(和 999999... 毫秒)之前的任何时间
这意味着您需要 1 月 1 日午夜后 0.0 到 9.999999999 天之间的记录....
但是当你运行查询时,你只是在问:
BETWEEN #1 jan 1900# and #10 jan 1900#
在 SQL 术语中,这是
BETWEEN 0.0 and 9.0
而不是你想要的:
BETWEEN 0.0 and 9.9999999999999999999999999....
最终,午夜是一天中发生的第一件事。您不会获得 1 月 10 日早上 6 点的任何记录,因为那是午夜之后,它是一个十进制数,例如 9.25
我相信你能理解 9.25 不在 0.0 和 9.0 之间
然而,您将获得恰好在 10 日午夜发生的记录,因为它们在内部表示为 9.0,而 9.0 介于 0.0 和 9.0 之间
所以您需要改变查询的方式:
date >= startdate AND date < enddate_plus_one_day
即在内部日期表示 tersm 中,如果你想获得早上 6 点的日期,即 1900 年 1 月 1 日之后的 9.25 天,那么你需要查询 date >= 0.0 and date < 10.0
- 这将 return 记录一直向上包括 23:59:59
我还抱怨你的查询风格——你将日期作为字符串传递,并希望 sql 服务器会找出你的答案。不要这样做。明确:
SELECT *
FROM ProjectDetails
where SubmittedDate >= CONVERT(datetime, @Year, 112)--pass date as string in yyyymmdd
AND SubmittedDate < (CONVERT(datetime, @Rtype, 112)+1.0) --pass date as a string in yyyymmdd
我正在尝试根据输入的开始和结束范围查找提交的数据。
假设我今天提交了数据,6 月 30 日
当我给出开始日期 6 月 1 日和结束日期 6 月 30 日的范围时,我没有得到今天提交的数据。当我给出开始日期 6 月 1 日和结束日期 7 月 1 日时,我得到了今天提交的数据。如何在 where 子句中也包含开始和结束日期?
AS
BEGIN
@Year navchar(200) = null
@Rtype navchar(200) = = null
SELECT *
FROM ProjectDetails
where SubmittedDate Between @Year and @Rtype
END
- --Convert The Date And check The Result Output
DECLARE
@Year NVARCHAR(200) = null,
@Rtype NVARCHAR(200) = null
SELECT *
FROM ProjectDetails
WHERE CONVERT(NVARCHAR, SubmittedDate,111) >= CONVERT(NVARCHAR,@Year,111) AND CONVERT(NVARCHAR,
SubmittedDate,111)<= CONVERT(NVARCHAR,@Rtype,111)
这是因为您误解了日期的工作原理。您将日期作为字符串传递和使用的事实进一步证明了这一点
首先,sql 服务器内部的日期表示为自某个日期(1900 年 1 月 1 日午夜)以来的天数
这意味着 1900 年 1 月 2 日在 sql 服务器内部表示为 1.0。 1900 年 1 月 2 日的 1800 小时日期在内部表示为 1.75 - 因为自第一个午夜以来已经有 1.75 天。下午 6 点是一天 24 小时的四分之三,因此内部表示中的 .75 部分
到目前为止和我在一起吗?
是小数点部分打败了你的逻辑
让我们看一个例子
假设您想要 1900 年 1 月 1 日到 1900 年 1 月 10 日之间的记录,所以实际上,您想要的记录在 1900 年 1 月 10 日 23:59:59(和 999999... 毫秒)之前的任何时间
这意味着您需要 1 月 1 日午夜后 0.0 到 9.999999999 天之间的记录....
但是当你运行查询时,你只是在问:
BETWEEN #1 jan 1900# and #10 jan 1900#
在 SQL 术语中,这是
BETWEEN 0.0 and 9.0
而不是你想要的:
BETWEEN 0.0 and 9.9999999999999999999999999....
最终,午夜是一天中发生的第一件事。您不会获得 1 月 10 日早上 6 点的任何记录,因为那是午夜之后,它是一个十进制数,例如 9.25
我相信你能理解 9.25 不在 0.0 和 9.0 之间
然而,您将获得恰好在 10 日午夜发生的记录,因为它们在内部表示为 9.0,而 9.0 介于 0.0 和 9.0 之间
所以您需要改变查询的方式:
date >= startdate AND date < enddate_plus_one_day
即在内部日期表示 tersm 中,如果你想获得早上 6 点的日期,即 1900 年 1 月 1 日之后的 9.25 天,那么你需要查询 date >= 0.0 and date < 10.0
- 这将 return 记录一直向上包括 23:59:59
我还抱怨你的查询风格——你将日期作为字符串传递,并希望 sql 服务器会找出你的答案。不要这样做。明确:
SELECT *
FROM ProjectDetails
where SubmittedDate >= CONVERT(datetime, @Year, 112)--pass date as string in yyyymmdd
AND SubmittedDate < (CONVERT(datetime, @Rtype, 112)+1.0) --pass date as a string in yyyymmdd