我有以下 SP:
SELECT
moncallAdd.FirstListing,
DATEADD(MINUTE, mOnCallAdd.StartOnCallTime,
DATEADD(DAY, mOnCallAdd.StartOnCallDate, '12/31/1899')) AS OnCallStart,
DATEADD(MINUTE, mOnCallAdd.duration,
DATEADD(MINUTE, mOnCallAdd.StartOnCallTime,
DATEADD(DAY, mOnCallAdd.StartOnCallDate, '12/31/1899'))) AS OnCallEnd
FROM
mdr.dbo.mOnCallAdd
where DATEADD(DAY, mOnCallAdd.StartOnCallDate, '12/31/1899')= DATEADD(ms , 0 - DATEPART(ms , GETDATE()) ,
DATEADD(s , 0 - DATEPART(s , GETDATE()) , GETDATE())) and
mOnCallAdd.SchedName = 'arc im'
UNION
SELECT
moncallDelete.FirstListing,
DATEADD(MINUTE, mOnCallDelete.StartOnCallTime,
DATEADD(DAY, mOnCallDelete.StartOnCallDate, '12/31/1899')) AS OnCallStart,
DATEADD(MINUTE, mOnCallDelete.duration,
DATEADD(MINUTE, mOnCallDelete.StartOnCallTime,
DATEADD(DAY, mOnCallDelete.StartOnCallDate, '12/31/1899'))) AS OnCallEnd
FROM
mdr.dbo.mOnCallDelete
where DATEADD(DAY, mOnCallDelete.StartOnCallDate, '12/31/1899')= DATEADD(ms , 0 - DATEPART(ms , GETDATE()) ,
DATEADD(s , 0 - DATEPART(s , GETDATE()) , GETDATE())) and
mOnCallDelete.SchedName = 'arc im'
Run Code Online (Sandbox Code Playgroud)
我想要做的是如下:
如果我有一个从今天上午 9 点运行到今天下午 5 点的时间表,并且我在该时间范围内的任何时间运行我的 SP,我希望将该时间表作为我的数据集的一部分。我可以单独为约会工作,但无法弄清楚时间部分。任何人都可以提供任何帮助吗?
附录(是一个答案,合并了 -- jcolebrand)
理查德,
首先让我感谢您对这张桌子设计的见解,我同意您的观点,它设计得很差,但我没有设计它(感谢上帝。)其次,我尝试了您的查询,我正在变得更好结果,但它仍然没有消除所有不应返回的数据。以下是我的数据集中不应该出现的两个结果:
HEART HOSPITAL - xxxxx 2011-08-15 19:00:00.000 2011-08-16 07:00:00.000
HEART HOSPITAL - xxxxx 2011-08-15 13:00:00.000 2011-08-15 19:00:00.000
Run Code Online (Sandbox Code Playgroud)
(查询是在 9:18 CST 运行的,所以这些还不会发生。)
当我运行此查询时:
SELECT DATEADD(DAY,38490,'12/31/1899'), CAST(CONVERT(VARCHAR(10), getdate(), 111) AS DATETIME)
Run Code Online (Sandbox Code Playgroud)
(38490 是我的 StartOncallDate 字段的第一个值中的 int)
它返回一个值:
2005-05-19 00:00:00.000 2011-08-15 00:00:00.000
Run Code Online (Sandbox Code Playgroud)
这里还有我的表中的几行数据:
Rec Id Timestamp SchedName StartOnCallDate StartOncallTime FirstListing Duration AddDate AddTime
70550 55426893 BITTAR&ESKEW 38490 1020 YIUM 840 38490 1293
70551 55427287 ZZOB02 38494 1020 CARTER, KIMBERLY 900 38491 247
Run Code Online (Sandbox Code Playgroud)
1) 我不打算争论数据库设计,因为它似乎已经到位。
2) 查看代码,我必须假设 StartOnCallDate、StartOnCallTime 和 Duration 是整数。如果您尝试使用 DATETIME 来做到这一点,那么还有其他问题需要处理。
要回答你的问题...
首先, where 子句中的数学仍然包括时间(小时和秒)。所以这个东西:
DATEADD(ms , 0 - DATEPART(ms , GETDATE()) ,
DATEADD(s , 0 - DATEPART(s , GETDATE()) , GETDATE()))
Run Code Online (Sandbox Code Playgroud)
给出了这个结果:
SELECT DATEADD(ms , 0 - DATEPART(ms , GETDATE()) ,
DATEADD(s , 0 - DATEPART(s , GETDATE()) , GETDATE()))
-----------------------
2011-08-12 15:35:00.000
Run Code Online (Sandbox Code Playgroud)
因此,当您将 DATEADD(DAY, mOnCallAdd.StartOnCallDate, '12/31/1899') 与上面的混乱进行比较时,它几乎永远不会相等。那是因为当您使用 DATEADD(DAY...) 到那个硬编码日期时,您最终只会得到天数:
SELECT DATEADD(DAY, 40800, '12/31/1899')
-----------------------
2011-09-15 00:00:00.000
Run Code Online (Sandbox Code Playgroud)
为了减少小时和秒,你可以做更多的 DATEADD 东西,或者你可以做这样的事情:
(SQL Server 2008):
CONVERT (date, GETDATE())
(SQL Server 2005/2008 options):
CAST(CONVERT(VARCHAR(10), getdate(), 101) AS DATETIME)
CAST(FLOOR(CAST(GETDATE() AS DECIMAL(12, 5))) AS DATETIME)
Run Code Online (Sandbox Code Playgroud)
这些只会让你知道日期。如果您将其中之一放入 where 子句中,它将允许您过滤数据,向您显示与当前 DAY 匹配的所有值(今天将发生的任何事情):
WHERE DATEADD(DAY, mOnCallAdd.StartOnCallDate, '12/31/1899')=
CAST(CONVERT(VARCHAR(10), getdate(), 101) AS DATETIME) AND
mOnCallAdd.SchedName = 'arc im'
Run Code Online (Sandbox Code Playgroud)
为了让您了解您正在比较的值,请将每个值(带有示例数据)提取到一个 select 语句中:
SELECT
DATEADD(DAY, 40766, '12/31/1899'),
CAST(CONVERT(VARCHAR(10), getdate(), 101) AS DATETIME)
----------------------- -----------------------
2011-08-12 00:00:00.000 2011-08-12 00:00:00.000
Run Code Online (Sandbox Code Playgroud)
现在,要过滤掉任何可能已经通过的内容,您需要向 WHERE 子句添加一个条件,以检查结束时间以确定它是否早于当前时间。
DATEADD(MINUTE, mOnCallAdd.duration,
DATEADD(MINUTE, mOnCallAdd.StartOnCallTime,
DATEADD(DAY, mOnCallAdd.StartOnCallDate, '12/31/1899'))) > GetDate()
Run Code Online (Sandbox Code Playgroud)
这使得整个 where 子句:
WHERE DATEADD(DAY, mOnCallAdd.StartOnCallDate, '12/31/1899')=
CAST(CONVERT(VARCHAR(10), getdate(), 111) AS DATETIME) AND
DATEADD(MINUTE, mOnCallAdd.duration,
DATEADD(MINUTE, mOnCallAdd.StartOnCallTime,
DATEADD(DAY, mOnCallAdd.StartOnCallDate, '12/31/1899'))) > GetDate() AND
mOnCallAdd.SchedName = 'arc im'
Run Code Online (Sandbox Code Playgroud)
编辑:
如果您只想显示当前正在发生的项目,您需要在结束时间(如上)和开始时间上都符合条件。要限定您的开始时间,您需要获取您的开始时间并确保当前时间大于或等于当前时间:
DATEADD(MINUTE, mOnCallAdd.StartOnCallTime,
DATEADD(DAY, mOnCallAdd.StartOnCallDate, '12/31/1899')) <= GetDate()
Run Code Online (Sandbox Code Playgroud)
这使得整个 WHERE 子句:
WHERE DATEADD(DAY, mOnCallAdd.StartOnCallDate, '12/31/1899')=
CAST(CONVERT(VARCHAR(10), getdate(), 111) AS DATETIME) AND
DATEADD(MINUTE, mOnCallAdd.duration,
DATEADD(MINUTE, mOnCallAdd.StartOnCallTime,
DATEADD(DAY, mOnCallAdd.StartOnCallDate, '12/31/1899'))) > GetDate() AND
DATEADD(MINUTE, mOnCallAdd.StartOnCallTime,
DATEADD(DAY, mOnCallAdd.StartOnCallDate, '12/31/1899')) <= GetDate() AND
mOnCallAdd.SchedName = 'arc im'
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
5979 次 |
最近记录: |