在我工作的公司,日期和时间值总是分别存储在整数字段中,所以例如今天早上8:30将存储如下:
然而,当我输入时间时,时间会像这样存储
不幸的是,如果我想在查询的WHERE子句中添加BETWEEN,则会引入轻微的复杂性。
目前我正在使用的系统正在使用这样的查询:
declare @minDate int, @minTime int, @maxDate int, @maxTime int
select @minDate = 20091102
select @minTime = 64841
select @maxDate = 20091105
select @maxTime = 102227
SELECT *
FROM transactions
WHERE
(
(
txnDate = @minDate AND
txnTime >= @minTime
) OR
txnDate > @minDate
) AND
(
(
txnDate = @maxDate AND
txnTime <= @maxTime
) OR
txnDate < @maxDate
)
请记住,我无法改变数据库的设计......
有更好的方法吗?
答案 0 :(得分:3)
如果将它们一起添加,例如:
cast(20091116 as bigint) * 1000000 + 183000
你可以做更简单的数学运算。例如:
select @minDate = 20091102064841
select @maxDate = 20091105102227
select *
from (
select cast(txnDate as bigint) * 1000000 +
txnTime as composite_date,
*
from YourTable
) sub
where composite_date between @minDate and @maxDate
另一种方法是将两个字段转换为实际的日期时间。您可以使用计算列执行此操作:
alter table YourTable add txnDateTime as cast(
cast(txnDate as varchar) + ' ' +
cast(txnTime / 10000 as varchar) + ':' +
cast(txnTime / 100 % 100 as varchar) + ':' +
cast(txnTime % 100 as varchar)
as datetime)
如果性能有问题,您可以使用PERSISTED关键字将计算列存储在磁盘上。
答案 1 :(得分:2)
如果你担心性能(因此在txnDate和txnTime上有索引),你应该使用它:
SELECT * FROM transactions
WHERE (txnDate > @minDate AND txnDate < @maxDate)
OR (txnDate = @minDate AND txnTime >= @minTime)
OR (txnDate = @maxDate AND txnTime <= @maxTime)
否则,Andomar对bigint的诀窍很清楚。
答案 2 :(得分:1)
重新定义@minDate和@maxDate
declare @minDate bigint, @maxDate bigint
select @minDate = 20091102064841
select @maxDate = 20091105102227
然后可能将查询简化为
SELECT *
FROM transactions
WHERE ((CAST(txnDate AS bigint) * 1000000) + txnTime) BETWEEN @minDate AND @maxDate
答案 3 :(得分:0)
您应该计算日期和时间组件,并创建一个包含DATETIME的值。你应该为@variables做同样的事情。然后你做比较。
这样做有几个优点,如数据验证,日期时间功能,准确性等。
declare @minDate int, @minTime int, @maxDate int, @maxTime int
select @minDate = 20091102
select @minTime = 64841
select @maxDate = 20091105
select @maxTime = 102227
DECLARE @MinDateTime DateTime
select @MinDateTime =
cast (convert (varchar, @minDate / 10000) + '/' +
convert (varchar, (@minDate % (@minDate / 10000))/100) + '/' +
convert (varchar, (@minDate % (@minDate / 1000000))) + ' ' +
convert (varchar, @minTime / 10000) + ':' +
convert (varchar, (@minTime % 10000)/100) + ':' +
convert (varchar, (@minTime % (@minTime / 100))) as datetime)
一旦定义了计算,就可以创建一个位于此表顶部的视图,并在任何进一步的计算中使用该视图,这样您就不必每次都重新键入计算。