【问题标题】:Adding Offset to Time Interval向时间间隔添加偏移量
【发布时间】:2011-04-04 22:35:15
【问题描述】:

我在 TimeZone 表中有两列 Interval 和 Offset,数据如下所示:

Interval             Offset
730                  60
830                  60
1000                 60

我也试图从这些中获得第三列,这会给我这样的:

Interval             Offset        Interval_Offset
730                  60            0830 
830                  60            0930
1000                 60            1100

select CONVERT(INT, interval / 100) + OFFSET / 60 
from Timezone

我只有一小时而不是一分钟。

谁能帮帮我?

【问题讨论】:

  • 这些列是什么意思?间隔是时间吗?秒?分钟?小时?什么是抵消? Interval_Offset 是多少?
  • @Abe Miessler 间隔是时间,偏移是分钟
  • 您是否将一天中的时间作为整数存储在“间隔”列中?
  • @Catcall Interval 是 varchar,Offset 是 int 类型

标签: sql sql-server tsql sql-server-2008 datetime


【解决方案1】:
declare @T table (interval varchar(4), offset int)

insert @T values
('730', 60),
('830', 60),
('1000', 60);

select
  interval,
  offset,
  replace(convert(char(5), dateadd(mi, convert(int, interval) % 100 + offset, dateadd(hour, convert(int, interval) / 100, 0)), 8),':','')
from @T

【讨论】:

  • @Sam - 没有区别。代码仍然有效。无论在何处使用,您都将获得从 varchar 到 int 的隐式转换。改为使用显式转换更新答案。
  • 它给出了正确的输出,但不是我得到输出为 02:30 的格式,但我希望输出为 0230
  • @Sam - 使用 replace 删除 :。更新了答案。
【解决方案2】:

您必须先转换为小时,然后是分钟才能准确地进行小时算术,如下所示:

with q1 as (
  select 730 interval, 60 offset
  union all
  select 830, 60
  union all
  select 1000, 60
  union all 
  select 1145, 30
  union all
  select 1130, 90
  ),
  q2 as (
  select interval, offset
         ,  interval / 100 int_hour
         , (interval % 100) + offset int_minute
    from q1
  )  
select interval, offset
       , (int_hour + int_minute / 60) * 100 + (int_minute % 60) result_hour
  from q2    

结果是:

interval    offset      result_hour
730         60          830
830         60          930
1000        60          1100
1145        30          1215
1130        90          1300

我添加了几个值来向您展示它在不同的时间间隔内运行良好。当然这仍然是有限的,如果它对你有用取决于我们对你所面临的问题的不了解..

【讨论】:

  • 我有数千条记录需要这种计算。所以我不认为我可以使用这段代码。
【解决方案3】:

日期和时间数学是出了名的难。我建议您使用正确的数据类型(即,由于您使用的是 SQL 2008,请为您的 Interval 列使用时间类型),然后使用 dateadd 为其添加偏移量。

【讨论】:

  • 内联呢?像“select dateadd(minute, offset, convert(time, interval)) from your_table”?
【解决方案4】:

一些数学..

create table TimeZone (interval int, offset int)
insert TimeZone values
(730, 60),
(830, 60),
(1000, 60);

select
    interval, offset,
    ((interval+offset+40)/100)*100 + ((interval+OFFSET)%100)%60 Interval_Offset
from Timezone

输出

interval    offset      Interval_Offset
----------- ----------- ---------------
730         60          830
830         60          930
1000        60          1100

另一方面,如果interval 是日期时间列,则可以使用

create table TimeZone (interval datetime, offset int)
insert TimeZone values ('7:30', 60), ('8:30', 60), ('10:00', 60);

select
    interval,
    convert(char(5),interval,8) Interval_display,
    offset,
    dateadd(mi, offset, interval) Interval_Offset,
    convert(char(5),dateadd(mi, offset, interval),8) Interval_Offset_display
from Timezone

输出(第 2 列和第 5 列格式化时间以 HH:MM 显示)

interval                Interval_display offset      Interval_Offset         Interval_Offset_display
----------------------- ---------------- ----------- ----------------------- -----------------------
1900-01-01 07:30:00.000 07:30            60          1900-01-01 08:30:00.000 08:30
1900-01-01 08:30:00.000 08:30            60          1900-01-01 09:30:00.000 09:30
1900-01-01 10:00:00.000 10:00            60          1900-01-01 11:00:00.000 11:00

【讨论】:

  • Interval 是 Varchar 数据类型。当我执行你的代码时,它给了我 interval(730) offset(60) Interval_Offset(790) 但我希望 Interval_Offset 是 Interval_Offset(830)
  • @Sam 你用的是哪一个?第一个应该使用 varchar 的间隔,只要所有的 varchar 只包含 INT。请注意,我没有使用 A+B,我使用 (A+40+B)/... 将 790 推到 830。
  • @Sam / 此外,直接整数数学将比两次转换为日期时间、进行日期数学、转换为字符然后最后进行替换要快
【解决方案5】:

由于 Interval 是时间类型(根据您的评论),您可以使用 DATEADD():

SELECT DATEADD(m, Offset, Interval)
FROM Timezone

【讨论】:

  • 间隔是 varchar 而不是日期时间
  • @Sam - 在您对原始问题的评论中,您说是时候了,我假设您的意思是 SQL 类型“时间”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-25
  • 1970-01-01
  • 2022-06-10
  • 1970-01-01
  • 2011-01-20
  • 2016-04-29
  • 1970-01-01
相关资源
最近更新 更多