SQL - 在 WHERE 子句中包含日期范围的结果集中未显示更正日期
SQL - Correct dates not being presented in result set with date ranges in WHERE clause
没有 where 子句的结果集显示有 9 月 30 日的数据,当使用下面的 where 子句时,第 30 个数据没有出现在结果集中(结果集见下图)- 我的主要目的是显示上个月的第一天和上个月的最后一天之间的数据 - 非常感谢任何帮助:
SQL 查询
DECLARE @date1 datetime
DECLARE @date2 datetime
SET @date1 = getdate()
SET @date2 = getdate()-15 -- reason for less 15 days is because this will only be run within the first 15 days
-- of the current month, it will enable me to get the last day of the previous
-- month even if I run the SQL in the next month.
SELECT
A.TA_SEQ as 'WO No',
A.TA_DUE_DATEUTC
FROM
F_TASKS A WITH (NOLOCK)
INNER JOIN FINFILE B WITH (NOLOCK) ON A.TA_FKEY_IN_SEQ = B.IN_SEQ
INNER JOIN InstructionSetGroups C WITH (NOLOCK) ON B.InstructionSetGroupId = C.InstructionSetGroupId
WHERE
A.TA_TASK_DESC = 'BREAKDOWN' AND
A.TA_STATUS IN ('ACTIVE', 'ASSIGNED', 'COMPLETE', 'HISTORY') AND
A.TA_DUE_DATE >= DATEADD(DAY, 1, EOMONTH(@date1, -2)) AND
A.TA_DUE_DATE <= EOMONTH(@date2)
ORDER BY
A.TA_DUE_DATE desc
结果集
在 where 子句中使用日期范围的结果集:
在 where 子句中未使用日期范围的结果集 - 如您所见,还有很多来自 30 日的数据未被捕获
我会采用不同的方法来处理您的日期值。整个 -15 的东西很奇怪,会在月底前几天引起问题。如果您了解一些日期数学,那么使用单个变量就足够了。
DECLARE @date1 date --use the data datatype here because time is important in this case
SET @date1 = getdate()
--this is to show you the values and can be removed.
select BeginningOfLastMonth = dateadd(month, datediff(month, 0, @date1) - 1, 0)
, BeginningOfCurrentMonth = dateadd(month, datediff(month, 0, @date1), 0)
--Your select statement here
where A.TA_DUE_DATE >= dateadd(month, datediff(month, 0, @date1) - 1, 0)
A.TA_DUE_DATE <= dateadd(month, datediff(month, 0, @date1), 0) --ANY datetime value less than this is before the end of last month
EOMONTH
非常模棱两可,因为它 returns 这个月的最后一天 午夜 。我在Will you use EOMONTH()?
里说说为什么我不喜欢这个功能
如果您想要整个上个月,有比假设代码会在前 15 天内 运行 更简单、更安全的方法:
DECLARE @ThisMonth date = DATEFROMPARTS(YEAR(GETDATE()), MONTH(GETDATE()), 1);
SELECT ... FROM ...
WHERE TA_DUE_DATE >= DATEADD(MONTH, -1, @ThisMonth)
AND TA_DUE_DATE < @ThisMonth;
我在 Simplify Date Period Calculations in SQL Server 中解释了为什么 DATEFROMPARTS
最适合这种工作。
剩下的,我们从哪里开始呢?
getdate()-15
是懒惰的,不直观的 shorthand 会在其他情况下中断。请使用 DATEADD(DAY, -15, GETDATE())
并查看 Bad Habits to Kick : Using shorthand with date/time operations。
您可以 declare/set 以比显式行更易读的方式为每个声明再为每个集合:
DECLARE @date1 datetime = GETDATE(),
@date2 datetime = DATEADD(DAY, -15, GETDATE());
as 'WO No'
- 请使用 AS [Wo No]
或 AS "Wo No"
- 字符串分隔符使这些别名看起来像字符串,并且不推荐使用该语法的某些形式.
请always specify the schema and never use meaningless aliases like A
, B
, C
.
>= AND <=
与 BETWEEN
相同。我谈论为什么 BETWEEN
对于 What do BETWEEN and the devil have in common?
中的日期范围总是一个糟糕的主意
I'm using NOLOCK; is that bad?
NOLOCK
上有很多资源
- 中的一般日期提示
没有 where 子句的结果集显示有 9 月 30 日的数据,当使用下面的 where 子句时,第 30 个数据没有出现在结果集中(结果集见下图)- 我的主要目的是显示上个月的第一天和上个月的最后一天之间的数据 - 非常感谢任何帮助:
SQL 查询
DECLARE @date1 datetime
DECLARE @date2 datetime
SET @date1 = getdate()
SET @date2 = getdate()-15 -- reason for less 15 days is because this will only be run within the first 15 days
-- of the current month, it will enable me to get the last day of the previous
-- month even if I run the SQL in the next month.
SELECT
A.TA_SEQ as 'WO No',
A.TA_DUE_DATEUTC
FROM
F_TASKS A WITH (NOLOCK)
INNER JOIN FINFILE B WITH (NOLOCK) ON A.TA_FKEY_IN_SEQ = B.IN_SEQ
INNER JOIN InstructionSetGroups C WITH (NOLOCK) ON B.InstructionSetGroupId = C.InstructionSetGroupId
WHERE
A.TA_TASK_DESC = 'BREAKDOWN' AND
A.TA_STATUS IN ('ACTIVE', 'ASSIGNED', 'COMPLETE', 'HISTORY') AND
A.TA_DUE_DATE >= DATEADD(DAY, 1, EOMONTH(@date1, -2)) AND
A.TA_DUE_DATE <= EOMONTH(@date2)
ORDER BY
A.TA_DUE_DATE desc
结果集
在 where 子句中使用日期范围的结果集:
在 where 子句中未使用日期范围的结果集 - 如您所见,还有很多来自 30 日的数据未被捕获
我会采用不同的方法来处理您的日期值。整个 -15 的东西很奇怪,会在月底前几天引起问题。如果您了解一些日期数学,那么使用单个变量就足够了。
DECLARE @date1 date --use the data datatype here because time is important in this case
SET @date1 = getdate()
--this is to show you the values and can be removed.
select BeginningOfLastMonth = dateadd(month, datediff(month, 0, @date1) - 1, 0)
, BeginningOfCurrentMonth = dateadd(month, datediff(month, 0, @date1), 0)
--Your select statement here
where A.TA_DUE_DATE >= dateadd(month, datediff(month, 0, @date1) - 1, 0)
A.TA_DUE_DATE <= dateadd(month, datediff(month, 0, @date1), 0) --ANY datetime value less than this is before the end of last month
EOMONTH
非常模棱两可,因为它 returns 这个月的最后一天 午夜 。我在Will you use EOMONTH()?
如果您想要整个上个月,有比假设代码会在前 15 天内 运行 更简单、更安全的方法:
DECLARE @ThisMonth date = DATEFROMPARTS(YEAR(GETDATE()), MONTH(GETDATE()), 1);
SELECT ... FROM ...
WHERE TA_DUE_DATE >= DATEADD(MONTH, -1, @ThisMonth)
AND TA_DUE_DATE < @ThisMonth;
我在 Simplify Date Period Calculations in SQL Server 中解释了为什么 DATEFROMPARTS
最适合这种工作。
剩下的,我们从哪里开始呢?
getdate()-15
是懒惰的,不直观的 shorthand 会在其他情况下中断。请使用DATEADD(DAY, -15, GETDATE())
并查看 Bad Habits to Kick : Using shorthand with date/time operations。您可以 declare/set 以比显式行更易读的方式为每个声明再为每个集合:
DECLARE @date1 datetime = GETDATE(), @date2 datetime = DATEADD(DAY, -15, GETDATE());
as 'WO No'
- 请使用AS [Wo No]
或AS "Wo No"
- 字符串分隔符使这些别名看起来像字符串,并且不推荐使用该语法的某些形式.请always specify the schema and never use meaningless aliases like
A
,B
,C
.
中的日期范围总是一个糟糕的主意>= AND <=
与BETWEEN
相同。我谈论为什么BETWEEN
对于 What do BETWEEN and the devil have in common?I'm using NOLOCK; is that bad?
NOLOCK
上有很多资源- 中的一般日期提示