Tsql 如何将int转换为时间(例如“1930”到“19:30”),并以小时和分钟(HH:MM)为单位获取开始和结束时间之间的差异?

Tsql 如何将int转换为时间(例如“1930”到“19:30”),并以小时和分钟(HH:MM)为单位获取开始和结束时间之间的差异?,tsql,sql-server-2008-r2,Tsql,Sql Server 2008 R2,我的表上有两列,其中包含输入和输出时间。我需要减去它们,得到所花费的时间,甚至把它们转换成时间或其他任何方式 CREATE TABLE [dbo].[FELData]( [RCIN1] [numeric](4, 0) NOT NULL, [RCOUT1] [numeric](4, 0) NOT NULL ) ON [PRIMARY] RCIN1 RCOUT1 Desire Result 150 1930 17:40 615

我的表上有两列,其中包含输入和输出时间。我需要减去它们,得到所花费的时间,甚至把它们转换成时间或其他任何方式

CREATE TABLE [dbo].[FELData](
    [RCIN1] [numeric](4, 0) NOT NULL,
    [RCOUT1] [numeric](4, 0) NOT NULL
) ON [PRIMARY]

RCIN1        RCOUT1     Desire Result
150          1930       17:40
615          1747       11:32
410          1830       14:20
400          1600       12:00
这是我到目前为止所做的,但没有返回正确的数字

SELECT rcin1, rcout1, DATEDIFF(mi,
    CAST(STUFF(RIGHT('0'+CAST(rcin1 AS VARCHAR(8)),4),3,0,':') AS DATETIME),
    CAST(STUFF(RIGHT('0'+CAST(rcout1 AS VARCHAR(8)),4),3,0,':') AS DATETIME)
    )/60.0 AS [Hours]   
FROM FELData;

RCIN1        RCOUT1     Returning
150          1930       17.66
615          1747       11.53
410          1830       13.25
400          1600       12.83
我怎样才能解决这个问题

更新

有时可能会出现用户数据输入错误,如

RCIN1        RCOUT1     Returning
49          1930        Should return 0

谢谢

您的第一个问题是将时间存储为数字, 但以下是如何将数字转换为时间数据类型:

declare @timeNumb int = 1500

    select 
        convert( time , (
reverse( substring( reverse( convert( varchar, @timeNumb) ) , 3, 2 ) ) + ':' +
reverse( substring( reverse( convert( varchar, @timeNumb) ) , 1, 2 ) )
                        ) 
                )
之后,使用datediff()应该会给出所需的间隔长度。

试试这个

-- temp table for data sample
DECLARE @FELData AS TABLE
    (
      [RCIN1] NUMERIC(4, 0) ,
      [RCOUT1] NUMERIC(4, 0)
    )
INSERT  INTO @FELData
        ( RCIN1, RCOUT1 )
VALUES  ( 150, 1930 ),
        ( 615, 1747 ),
        ( 410, 1830 ),
        ( 400, 1600 )

--Solution
SELECT  T.[RCIN1] ,
        T.[RCOUT1] ,
        RIGHT('0' + CONVERT(VARCHAR(2), T.M / 60), 2) + ':'
        + RIGHT('00' + CONVERT(VARCHAR(2), T.M % 60), 2) AS Duration
FROM    ( SELECT    FD.* ,
                    DATEDIFF(MINUTE,
                             CONVERT(TIME, STUFF(RIGHT('0'
                                                       + CONVERT(VARCHAR(8), FD.[RCIN1]),
                                                       4), 3, 0, ':')),
                             CONVERT(TIME, STUFF(RIGHT('0'
                                                       + CONVERT(VARCHAR(8), FD.[RCOUT1]),
                                                       4), 3, 0, ':'))) AS M
          FROM      @FELData AS FD
        ) T 
输出结果


这几乎满足了您的需求,但它无法识别491930是坏数据。你怎么知道的

由于您拥有的数据是数字的,因此无需将其转换为散文、拆分、解析、转换、重新组合等等。算算吧

[更新代码]

-- Sample data.
declare @Samples as Table ( RCIn1 Numeric(4,0), RCOut1 Numeric(4,0) );
insert into @Samples ( RCIn1, RCOut1 ) values
  ( 150, 1930 ), ( 615, 1747 ),  ( 410, 1830 ), ( 400, 1600 ),
  ( 49, 1930 ); -- This is allegedly "bad" data, but no explanation is given.
select * from @Samples;

with
  -- Numeric values converted to instances of TIME datatype.
  Times as (
    select RCIn1, RCOut1,
      Cast( DateAdd( minute, Floor( RCIn1 / 100 ) * 60 + RCIn1 % 100, 0 ) as Time ) as RCIn1Time,
      Cast( DateAdd( minute, Floor( RCOut1 / 100 ) * 60 + RCOut1 % 100, 0 ) as Time ) as RCOut1Time
    from @Samples )
  -- Calculate delta times.
  select *, Cast( DateAdd( minute, DateDiff( minute, RCIn1Time, RCOut1Time ), 0 ) as Time ) as DeltaTime
    from Times

使用right('0000'+convert(varchar,@timeNumb),4)可以确保值的长度为4个字符。至于处理不良数据,请使用案例说明或在计算前进行清理。无需使用上述HABO帖子的完整解决方案。我也不知道为什么49是“坏”数据——因为00:49是一个有效时间(午夜后49分钟)。