【问题标题】:How to convert time into days如何将时间转换为天
【发布时间】:2021-11-04 17:12:45
【问题描述】:

我在表格中得到了这些数据。使用 SQL 服务器。我需要创建一个报告,我需要在其中添加此持续时间并转换为天,持续时间列的数据类型是时间戳。当我对此使用 Sum 时,我收到此错误 Operand data type varchar is invalid for sum operator.

将其转换为天数的最佳方法是什么?

      <table>
        <thead>
        <tr>
        <th>TicketNumber</th>
        <th>duration</th>
        </tr>
        </thead>
        <tbody>
        <tr>
        <td>521163</td>
        <td>44:08:11</td>
        </tr>
        </tbody>
        <tbody>
        <tr>
        <td>906868</td>
        <td>404:55:27</td>
        </tr>
        </tbody>
        <tbody>
        <tr>
        <td>140013</td>
        <td>412:08:03</td>
        </tr>
        </tbody>
        </table>

【问题讨论】:

  • RowVersion,又名timestamp,不存储日期、时间或其任何组合。 RowVersion 的聚合没有意义。 Time,就其价值而言,仅限于 sum 各种 time 值来获得另一个数据类型的结果,该数据类型将代表一些天数?
  • 是的,就像我的值一样, 44:08:11 45:38:35 48:50:31 75:15:59 76:23:49 78:20:27 80:16 :08 81:17:28,需要添加这些值并将总小时数转换为天数
  • 请阅读this,了解一些改进问题的技巧。 44:08:11 45:38:35 48:50:31 75:15:59 76:23:49 78:20:27 80:16:08 81:17:28 不是 rowversion 值或有效的 IPv6 地址。如果没有实际的数据类型或预期的结果,我们将不得不做一些猜测来帮助您。这既浪费了您的时间,也浪费了我们的时间。您问题中神秘字符串的正确结果可能是N'XXXVI'。还是您需要(适当的)一天的时间?
  • 如果您有表格或 HTML 代码,从您的描述中不清楚。您谈论的是表格,但呈现的是 HTML 代码。如果您有一个表,那么我们需要获取一个 table = 查询来创建表并插入示例数据。如果您有需要解析的 HTML 代码,那么您没有表格,只有文本

标签: tsql datetime


【解决方案1】:

如果您有 TABLE 或 HTML 代码,从您的描述中不清楚!您谈论的是表格,但呈现的是 HTML 代码。

如果您有一个表,那么我们需要获取一个表,这意味着查询以创建表并插入示例数据。如果您有需要解析的 HTML 代码,那么您没有表格,只有文本。

假设您有问题中提供的 HTML 代码,那么您有一个 XML 代码,这意味着您可以使用函数 OPENXML 来解析来自此处提供的 HTML 代码的数据:

DECLARE @HTML as XML
SELECT @HTML = '
      <table>
        <thead>
        <tr>
        <th>TicketNumber</th>
        <th>duration</th>
        </tr>
        </thead>
        <tbody>
        <tr>
        <td>521163</td>
        <td>44:08:11</td>
        </tr>
        </tbody>
        <tbody>
        <tr>
        <td>906868</td>
        <td>404:55:27</td>
        </tr>
        </tbody>
        <tbody>
        <tr>
        <td>140013</td>
        <td>412:08:03</td>
        </tr>
        </tbody>
        </table>
'
SELECT @HTML

------------------ First we will learn how to parse the HTML data to get table structure
-- Note! This base on exact format of the HTML code!
-- Any change in the format will fail this solution
DECLARE @handle INT
DECLARE @PrepareXmlStatus INT  
EXEC @PrepareXmlStatus= sp_xml_preparedocument @handle OUTPUT, @HTML  

SELECT id, MyTime
FROM OPENXML(@handle, '/table/tbody/tr', 1)  
    WITH (
        id NVARCHAR(MAX) '(td)[1]',
        MyTime NVARCHAR(MAX) '(td)[2]'
    )

EXEC sp_xml_removedocument @handle

使用这种方法,我们现在可以使用上述查询的结果 SET 中的数据并计算时间的总和,如下所示(这应该是您的解决方案):

DECLARE @HTML as XML
SELECT @HTML = '
      <table>
        <thead>
        <tr>
        <th>TicketNumber</th>
        <th>duration</th>
        </tr>
        </thead>
        <tbody>
        <tr>
        <td>521163</td>
        <td>44:08:11</td>
        </tr>
        </tbody>
        <tbody>
        <tr>
        <td>906868</td>
        <td>404:55:27</td>
        </tr>
        </tbody>
        <tbody>
        <tr>
        <td>140013</td>
        <td>412:08:03</td>
        </tr>
        </tbody>
        </table>
'
DECLARE @handle INT
DECLARE @PrepareXmlStatus INT  
EXEC @PrepareXmlStatus= sp_xml_preparedocument @handle OUTPUT, @HTML  

---------------- Now we can use the above way of parsiong the HTML in order to calculate the SUM of the times
EXEC @PrepareXmlStatus= sp_xml_preparedocument @handle OUTPUT, @HTML  

;With MyCTE as (
SELECT id, MyTime
    FROM OPENXML(@handle, '/table/tbody/tr', 1)  
        WITH (
            id NVARCHAR(MAX) '(td)[1]',
            MyTime NVARCHAR(MAX) '(td)[2]'
        )
),
-- Convert Seconds, minutes, hours to INT and sum
MyCTE1 as(
    SELECT 
        MySec  = SUM(CONVERT(INT,PARSENAME(REPLACE(MyTime,':','.'),1))),
        MyMin  = SUM(CONVERT(INT,PARSENAME(REPLACE(MyTime,':','.'),2))),
        MyHour = SUM(CONVERT(INT,PARSENAME(REPLACE(MyTime,':','.'),3)))
    from MyCTE
),
-- Move from seconds to minutes and from minutes to hours if the value above 60
MyCTE2 as(
    SELECT 
        MySec  = (MySec%60),
        MyMin  = (MyMin + (MySec/60)) % 60, 
        MyHour = MyHour + ((MyMin + (MySec/60)) / 60)
    from MyCTE1
)
SELECT 
    CONVERT(VARCHAR(10), MyHour) + ':' + 
    RIGHT('00' + CONVERT(VARCHAR(2), MyMin),2) + ':' + 
    RIGHT('00' + CONVERT(VARCHAR(2), MySec),2) 
FROM MyCTE2

EXEC sp_xml_removedocument @handle 

使用现有表

如果您已经有一个表格(不是 HTML 代码)并且您只需要查找天数、小时数、分钟数、秒数,那么您只需要使用上述查询的结尾部分即可。我们不需要解析 HTML 代码,因此我们可以跳转到名为 MyCTE01 的 CTE。

例如,使用评论中提供的 op DDL+DML:

CREATE TABLE [dbo].[OpenTickets] ( [TicketNumber] [varchar](50) NULL ,[Duration] [varchar](20) NULL )
GO
INSERT INTO [dbo].[OpenTickets] VALUES 
    ( 521163 ,'44:08:11' ) ,( 746008 ,'45:38:35' ) ,( 120025 ,'48:50:31' ) ,( 780125 ,'75:15:59' ) ,( 903960 ,'76:23:49' ) ,
    ( 937883 ,'178:20:27' ) ,( 524404 ,'80:16:08' ) ,( 374972 ,'81:17:28' )
GO

SELECT * FROM [OpenTickets]
GO

;With MyCTE1 as(
    SELECT 
        MySec  = SUM(CONVERT(INT,PARSENAME(REPLACE([Duration],':','.'),1))),
        MyMin  = SUM(CONVERT(INT,PARSENAME(REPLACE([Duration],':','.'),2))),
        MyHour = SUM(CONVERT(INT,PARSENAME(REPLACE([Duration],':','.'),3)))
    from [OpenTickets]
),
-- Move from seconds to minutes and from minutes to hours if the value above 60
MyCTE2 as(
    SELECT 
        MySec  = (MySec%60),
        MyMin  = (MyMin + (MySec/60)) % 60, 
        MyHour = MyHour + ((MyMin + (MySec/60)) / 60)
    from MyCTE1
)
SELECT 
    MyDays = MyHour/24,
    Total = 'Days: ' + CONVERT(VARCHAR(10), MyHour/24) + ' and ' +
        CONVERT(VARCHAR(10), MyHour % 24) + ':' + 
        RIGHT('00' + CONVERT(VARCHAR(2), MyMin),2) + ':' + 
        RIGHT('00' + CONVERT(VARCHAR(2), MySec),2),
    TotalTime = CONVERT(VARCHAR(10), MyHour) + ':' + 
    RIGHT('00' + CONVERT(VARCHAR(2), MyMin),2) + ':' + 
    RIGHT('00' + CONVERT(VARCHAR(2), MySec),2) 
FROM MyCTE2
GO

【讨论】:

  • 您好 Ronen,非常感谢您的回复。我有一个表 SQL 数据库,两列,票号和持续时间。持续时间是解决问题的总时间。它是 HH:MM:SS 格式,但有些值为 146:20:49,现在需要创建一个报告并将此持续时间列转换为天数。我怎样才能做到这一点。例如票号 12345 花费时间 146:20:49,我如何将其转换为否。天?
  • @user3061338 , 请提供: (1) 查询以创建表并插入一些示例数据。 (2) 你的服务器版本是多少? (3) 根据样本数据,您希望从查询中得到什么预期结果。
  • 关于天的表示,您可以使用我在上面代码中使用的相同方法来查找 SUM 之后的分钟和小时。天数是除以 24 的小时数,停留的小时数是模 24 的小时数。如果您提供我要求您提供的缺失信息,那么我们将能够提供具体的样本
  • 按要求创建表 [dbo].[OpenTickets] ( [TicketNumber] [varchar](50) NULL ,[Duration] [varchar](20) NULL ) INSERT INTO [dbo].[OpenTickets ] 值 (521163,'44:08:11'),(746008,'45:38:35'),(120025,'48:50:31'),(780125,'75:15:59'), (903960,'76:23:49'),(937883,'178:20:27'),(524404,'80:16:08'),(374972,'81:17:28')
  • 需要持续时间(以天为单位)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-29
相关资源
最近更新 更多