【问题标题】:Convert hh:mm to minutes in SQL Server在 SQL Server 中将 hh:mm 转换为分钟
【发布时间】:2020-05-11 02:19:02
【问题描述】:

我有来自源系统的数据,该系统以 hh:mm nvarchar 格式发送时间。我正在尝试将其转换为分钟。我只想根据需要在 SSRS 报告中执行此操作。所以,我正在寻找一个 SSRS 表达式而不是 T-SQL。

我的数据如下所示:

10:00
-2:00
-11:30

预期输出:

600
-120
-690

这是我迄今为止尝试过的,但正在寻找一种更好/性能更高效的方法

SUM(CInt(LEFT(Replace(Fields!HHMM.Value, "-", ""),InStrRev(Replace(Fields!HHMM.Value, "-", ""),":")-1))*60 + 
CInt(RIGHT(Replace(Fields!HHMM.Value, "-", ""),InStrRev(Replace(Fields!HHMM.Value, "-", ""),":")))
)

谢谢!

【问题讨论】:

  • 是否有太多可能的值无法使用查找表?它会非常快。
  • 是的!可能有多个值。
  • 太多可能的值可能在 >10,000,000 的范围内。 Report Builder Functions - Lookup Function.
  • 哦!不,只有少数几个值。但是,由于这是一份临时报告,我不确定是否值得使用查找表,因为这更像是对数据进行修饰。
  • 您写了“寻找更好/性能更高效的方法”。查找表会给你。

标签: sql-server vb.net reporting-services ssrs-2012


【解决方案1】:

这与 forpas 在 SSRS 语法中所做的类似。

=LEFT(Fields!TIME.Value, INSTR(Fields!TIME.Value, ":") - 1) * 60 + 
    IIF(LEFT(Fields!TIME.Value, 1) = "-", -1, 1) * 
    MID(Fields!TIME.Value, INSTR(Fields!TIME.Value, ":") + 1, 10)

【讨论】:

  • 谢谢!这似乎比我尝试的要好一些。我已将我的回复添加到我的原始帖子中。
  • 我刚刚再次验证了数据,如果有负号,您的代码似乎没有放负号。
  • 我在一个文本框中尝试了它,11:30-690 结束,所以它似乎工作正常。您的数据是否不同 - 可能是其中的空格?您将 LEFT 和 MID 函数包装在 INT() 函数中以尝试解析空格。
  • 不,我的数据中没有空格。
【解决方案2】:

使用字符串函数并转换为整数:

select
  cast(left(timecol, charindex(':', timecol) - 1) as int) * 60 +
  case when left(timecol, 1) = '-' then -1 else 1 end *
  cast(substring(timecol, charindex(':', timecol) + 1, len(timecol)) as int)
from tablename

或不通过隐式转换为整数进行强制转换:

select
  left(timecol, charindex(':', timecol) - 1) * 60 +
  case when left(timecol, 1) = '-' then -1 else 1 end *
  substring(timecol, charindex(':', timecol) + 1, len(timecol))
from tablename

timecol 替换为列的实际名称。
请参阅demo
结果:

 600
-120
-690

【讨论】:

  • 谢谢@forpas!但正如我的问题中提到的,我正在寻找一个 SSRS 解决方案而不是 SQL 解决方案。
【解决方案3】:

这可以做你想做的事:

TSQL:

select (case when CONVERT(integer,Replace('-11:30',':','')) < 0 then -1 else 1 end ) * ((DATEPART(HOUR,CONVERT(Datetime,Replace('-11:30','-',''))) * 60) + DATEPART(MINUTE,CONVERT(Datetime,Replace('-11:30','-',''))))

编辑:

您可以将我发布的TSQL 查询翻译成类似这样的内容,以便在SSRS 中使用它(请注意,我没有测试SSRS 代码):

Switch(Cint(Replace(Fields!timeField.Value,":","")) < 0,-1,Cint(Replace(Fields!timeField.Value,":","")) >= 0,1) * ((Hour(cdate(Replace(Fields!timeField.Value,":",""))) * 60 ) + Minute(cdate(Replace(Fields!timeField.Value,":",""))))

【讨论】:

  • 谢谢@Karamafrooz!但正如我的问题中提到的,我正在寻找一个 SSRS 解决方案而不是 SQL 解决方案。
  • @Julaayi 对不起,我没有注意到,我编辑了我的答案。
【解决方案4】:

你可以使用标量函数

CREATE FUNCTION fn_To_Min
(
    @timeVar nvarchar(10)
)
RETURNS int
AS
BEGIN

    declare @op char(1) = SUBSTRING(@timeVar, 1, 1)
    if(@op = '-')
    begin
        set @timeVar = SUBSTRING(@timeVar, 2, LEN(@timeVar))
    end
    else
        set @op = ''

    declare @time time = CONVERT( TIME, @timeVar )

    declare @h int = DATEPART(hh, @time)
    declare @m int = DATEPART(Minute, @time)

    RETURN CONVERT(int, CONCAT(@op, (@h * 60) + @m))

END

致电

SELECT fn_To_Min('10:25'), col1, col2, ...

【讨论】:

  • 谢谢,但我只是在寻找 SSRS 表达式而不是 SQL 代码。
【解决方案5】:

在我的情况下,这也是处理 SSRS 中的(空)值的方法。

IIF(Left(Fields!TIME.Value, 1) = "-", "-", "") &  
Right("000" & CInt(Replace(LEFT(Replace(Fields!TIME.Value, "-", ""), (INSTR(Replace(Fields!TIME.Value, "-", ""), ":"))), ":", "")) * 60 + 

CInt(IIF(IsNumeric(MID(Fields!TIME.Value, INSTR(Fields!TIME.Value, ":") + 1, 10)), 
                    MID(Fields!TIME.Value, INSTR(Fields!TIME.Value, ":") + 1, 10), 
                    Nothing
        ))
, 3)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-05
    相关资源
    最近更新 更多