【问题标题】:How to parse SQL Server String in hour, min and second如何以小时、分钟和秒为单位解析 SQL Server 字符串
【发布时间】:2021-02-04 18:12:01
【问题描述】:

我将时间存储为PT1H22M59.551S
那里的读数是 1 小时 22 分 59.551 秒。

最有效的拆分方法是什么?

数据可能是这样的。所以没有分隔符是强制性的

PT0S
PT6H4M29.212S
PT0S
PT2M55.126S
PT54M4.12S
PT3H6M5.74S
PT16H27M52.069S

【问题讨论】:

  • 你试过什么? SQL Server 有许多有用的功能可以帮助您。
  • 我发布了我尝试过的答案作为我自己的答案,但@TappDev60193 的答案似乎更好。显然,有可能解决这个问题,但我想使用最有效的方式,是的,我应该发布我尝试过的内容。

标签: sql sql-server string date parsing


【解决方案1】:
    --sql server
    declare @data table(
        lineid int identity, 
        [inboundTime] varchar(100)


    )
    insert @data([inboundTime]) select 'PT0S'
    insert @data([inboundTime]) select 'PT6H4M29.212S'
    insert @data([inboundTime]) select 'PT0S'
    insert @data([inboundTime]) select 'PT2M55.126S'
    insert @data([inboundTime]) select 'PT54M4.12S'
    insert @data([inboundTime]) select 'PT3H6M5.74S'
    insert @data([inboundTime]) select 'PT16H27M52.069S'
    insert @data([inboundTime]) select 'PT52.069S'

      update @data
        set [inboundTime] = replace([inboundTime],'PT','')

    SELECT  

             INBOUND_H
          ,  INBOUND_M
          ,  INBOUND_S
          ,  INBOUND_H*3600 + INBOUND_M*60  inboundTimeMin
          , [inboundTime]
    from (
    SELECT  

            IIF (   CHARINDEX('H', [inboundTime]) > 0 ,   SUBSTRING([inboundTime],  0, CHARINDEX('H', [inboundTime])),0)  INBOUND_H
          , IIF (   CHARINDEX('M', [inboundTime]) > 0 ,    SUBSTRING([inboundTime], CHARINDEX('H', [inboundTime])+1,CHARINDEX('M', [inboundTime]) - CHARINDEX('H', [inboundTime])-1 ), 0) INBOUND_M
          , SUBSTRING([inboundTime], CHARINDEX('M', [inboundTime])+1,CHARINDEX('S', [inboundTime]) - CHARINDEX('M', [inboundTime])-1 ) INBOUND_S
          , [inboundTime]
  
      FROM @data)x

【讨论】:

    【解决方案2】:

    您还可以创建一个函数来执行基本文本操作的转换:

    CREATE FUNCTION dbo.f_GetTime(@TimeInput VARCHAR(50)) RETURNS TIME
    AS BEGIN
        SET @TimeInput = REPLACE(REPLACE(@TimeInput, 'PT', ''), 'S', '')
        IF CHARINDEX('H', @TimeInput) = 0 -- Add missing H
            SET @TimeInput = '0H' + @TimeInput
        IF CHARINDEX('M', @TimeInput) = 0 -- Add missing M
            SET @TimeInput = REPLACE(@TimeInput, 'H', 'H0M')
        RETURN CONVERT(TIME, REPLACE(REPLACE(@TimeInput, 'H', ':'), 'M', ':'))
    END
    GO
    

    然后您可以将它与标量查询一起使用:

    SELECT dbo.f_GetTime('PT1H22M59.551S') AS TimeValue
    

    或者您可以将其与表格一起使用:

    DECLARE @Input TABLE (TimeInput VARCHAR(20))
    INSERT @Input VALUES ('PT1H22M59.551S'), ('PT0S'), ('PT6H4M29.212S'), ('PT0S'),
        ('PT2M55.126S'), ('PT54M4.12S'), ('PT3H6M5.74S'), ('PT16H27M52.069S')
    SELECT TimeInput, dbo.f_GetTime(TimeInput) AS TimeValue FROM @Input
    

    这将返回:

    TimeInput            TimeValue
    -------------------- ----------------
    PT1H22M59.551S       01:22:59.5510000
    PT0S                 00:00:00.0000000
    PT6H4M29.212S        06:04:29.2120000
    PT0S                 00:00:00.0000000
    PT2M55.126S          00:02:55.1260000
    PT54M4.12S           00:54:04.1200000
    PT3H6M5.74S          03:06:05.7400000
    PT16H27M52.069S      16:27:52.0690000
    

    【讨论】:

      【解决方案3】:
      --sql server
      declare @data table(
          lineid int identity, 
          a varchar(100),
          b varchar(100),
          hr varchar(20),
          [minute] varchar(20),
          [second] varchar(20)
      )
      insert @data(a) select 'PT0S'
      insert @data(a) select 'PT6H4M29.212S'
      insert @data(a) select 'PT0S'
      insert @data(a) select 'PT2M55.126S'
      insert @data(a) select 'PT54M4.12S'
      insert @data(a) select 'PT3H6M5.74S'
      insert @data(a) select 'PT16H27M52.069S'
      
      update @data
          set b = replace(a,'PT','')
      
      update @data
          set hr = LEFT(b,charindex('H',b))
      
      update @data
          set b = REPLACE(b,hr,'')
      
      update @data
          set [minute] = LEFT(b,charindex('M',b))
      
      update @data
          set b = REPLACE(b,[minute],'')
      
      update @data
          set [second] = LEFT(b,charindex('S',b))
      
      update @data
          set b = REPLACE(b,[second],'')
      
      update @data
          set [hr] = REPLACE([hr],'H',''),[minute]=REPLACE([minute],'M',''),[second]=REPLACE([second],'S','')
      
      update @data
          set hr = isnull(nullif(hr,''),'0'),[minute] = isnull(nullif([minute],''),'0'),[second] = isnull(nullif([second],''),'0')
      
      select *,
          [hr] + ' hour'+ case when hr <> '1' then 's ' else ' ' end +
          [minute] + ' minute'+ case when [minute] <> '1' then 's ' else ' ' end +
          [second] + ' second(s)'
      from @data
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-09-12
        • 2010-12-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-26
        • 2013-11-04
        相关资源
        最近更新 更多