我的数据带有DATETIME列的时间戳,我希望将其过滤到DATETIME在任何一天的上午9:30到下午5:30之间的记录集。最好的方法是什么?
更新:改变因为我需要精确到分钟,而不仅仅是小时。对不起。
答案 0 :(得分:2)
您可以随时将其编写为用户定义函数,特别是如果您需要定期执行此操作
CREATE function dbo.timepart (@date as SMALLDATETIME)
RETURNS SMALLDATETIME
AS
BEGIN
RETURN @date - DATEADD(d, DATEDIFF(d,0,@date), 0)
END
然后像这样使用
SELECT * FROM table
WHERE dbo.timepart(date_field) BETWEEN '9:30' AND '17:30'
在SQL Server 2005中使用以下测试
DECLARE @dates TABLE (date DATETIME)
DECLARE @date DATETIME
SET @date = '20 MAR 2009'
WHILE @date < '22 MAR 2009'
BEGIN
INSERT INTO @dates VALUES(@date)
SET @date = DATEADD(hour, 1, @date)
END
SELECT *
FROM
@dates
WHERE
dbo.timepart(date) BETWEEN '9:30' AND '17:30'
结果
date
-----------------------
2009-03-20 10:00:00.000
2009-03-20 11:00:00.000
2009-03-20 12:00:00.000
2009-03-20 13:00:00.000
2009-03-20 14:00:00.000
2009-03-20 15:00:00.000
2009-03-20 16:00:00.000
2009-03-20 17:00:00.000
2009-03-21 10:00:00.000
2009-03-21 11:00:00.000
2009-03-21 12:00:00.000
2009-03-21 13:00:00.000
2009-03-21 14:00:00.000
2009-03-21 15:00:00.000
2009-03-21 16:00:00.000
2009-03-21 17:00:00.000
答案 1 :(得分:1)
与上述代码类似,只需为您的MINUTE要求添加DATEPART(mi,列)
但是,请注意,这将会影响性能,因为列上的函数将避免使用索引(非sargeable)
如果您使用的是SQL 2008,则可以使用DATE和TIME新数据类型进行比较。如果没有,在SQL 2005中,也许您可以为TIME部分创建计算列并使用它
答案 2 :(得分:0)
SELECT *
FROM table1
WHERE
(DatePart(hh, DateColumn) >= 9 and DatePart(mm, DateColumn) >= 30)
AND (DatePart(hh, DateColumn) <= 17 AND DatePart(mm, DateColumn) <= 30)
答案 3 :(得分:0)
SELECT
*
FROM
My_Table
WHERE
DATEPART(hh, some_date) BETWEEN 9 AND 16 OR
(DATEPART(hh, some_date) = 17 AND DATEPART(mm, some_date) = 0...)
可替换地:
SELECT
*
FROM
My_Table
WHERE
DATEADD(dd, 1-DATEPART(dd, some_date),
DATEADD(mm, 1-DATEPART(mm, some_date),
DATEADD(yy, 1900-DATEPART(yy, some_date), some_date)))
BETWEEN @start_time AND @end_time
只需使用所需时间制作@start_time和@end_time 1900-01-01。
这将排除05:00:00.000 PM,但您应该可以根据需要进行调整。另请注意,它无法有效地使用索引进行此搜索。如果时间通常用于搜索或计算,您可以考虑将其分开并将DATE和TIME保持为两列。
答案 4 :(得分:0)
SELECT *
FROM your_table
WHERE (DATEPART(hh, date_column) = 9 AND DATEPART(mi, date_column) >= 30)
OR (DATEPART(hh, date_column) = 17 AND DATEPART(mi, date_column) <= 30)
OR DATEPART(hh, date_column) BETWEEN 10 AND 16
答案 5 :(得分:0)
这样的事情:
...
WHERE
(DATEPART(hh, some_date) BETWEEN 10 AND 16)
OR
(DATEPART(hh, some_date) = 9 AND DATEPART(mi, some_date) >= 30)
OR
(DATEPART(hh, some_date) = 17 AND DATEPART(mi, some_date) <= 30)
或者:
...
WHERE
LEFT(CONVERT(VARCHAR, some_date, 8), 5) >= '09:30' AND
LEFT(CONVERT(VARCHAR, some_date, 8), 5) <= '17:30'
甚至:
...
WHERE
LEFT(CONVERT(VARCHAR, some_date, 8), 5) BETWEEN '09:30' AND '17:30'
任何这些查询都不能使用索引。要使用索引,请以某种方式预先计算值,并将它们存储在索引列中。
答案 6 :(得分:0)
连接小时和分钟并比较范围。
with Result as (
select [Time] = cast(cast(datepart(hh, AuditDate) as varchar) +
cast(datepart(mi, AuditDate) as varchar) as int), *
from AuditTable
)
select *
from Result
where [Time] between 930 and 1730
答案 7 :(得分:0)
Select * from tbl
where ts between
convert(datetime,convert(varchar,ts, 101)) + convert(datetime,'9:30 am')
And Convert(datetime,convert(varchar,ts,101)) + convert(datetime,'5:30 pm')
我认为这将使用索引。我无法测试,我发布了这个用ipod
[从我的电脑编辑]
create function dbo.DaysTime(@date as datetime, @time datetime)
returns datetime
as
begin
/* datediff approach on scraping the
time part of datetime: inspired by Russ Cam */
return dateadd(d, datediff(d, 0, @d), 0)/*the date's day*/ + @time
end
select * from tbl where ts
between dbo.DaysTime(ts, '9:30 AM') and dbo.DaysTime(ts, '5:30 PM')
这仍然会使用索引,因为我们没有在where条件的左侧放置一个表达式。