2010-09-16 21 views
4

我在两个已设置为整数而不是时间戳的字段上比较SQL时间。将SQL编号转换为时间,执行日期比较

我在开发者最初设置为int(8)的数据库中有一些性能指标。数据库包含事务的开始和结束时间。例如

一些样本数据可能

id | start_time | end_time 
--------------------------- 
1 |  85958 | 90001 

如果我只是减去两个值,我会得到4043秒,当交易时间只有3个。但是我在努力将这些值转换成时间格式,允许我执行日期比较。

我无法在应用程序中进行此计算,因为每天数据库中有100行,我试图计算事务的平均和最大时间。

编辑:

为了澄清

的时间以秒 85958代表8点59分58秒90001代表9点00分01秒

更糟糕的是1分钟过了午夜0 :01:00将被表示为100.

+0

我相信这些都是毫秒,也许从开始过去了。 – 2010-09-16 18:35:26

回答

0

已经描述的大部分答案都是有效的,但不幸的是,iSeries似乎对不同的功能有所质疑,所以我不得不定制给出的答案以使其起作用。

最终的解决方案,我得到的是

select TIME(SUBSTR(DIGITS(END_TIME),1,2) CONCAT ':' CONCAT SUBSTR(DIGITS(END_TIME),3,2) CONCAT ':' CONCAT SUBSTR(DIGITS(END_TIME),5,2)) - TIME(SUBSTR(DIGITS(START_TIME),1,2) CONCAT ':' CONCAT SUBSTR(DIGITS(START_TIME),3,2) CONCAT ':' CONCAT SUBSTR(DIGITS(START_TIME),5,2)) from table1;

感谢所有的迅速和详细的答复

+0

显示的内容对于END_TIME和START_TIME的暗示DDL [列属性]不起作用,显然是INT(8)或INTEGER;即INTEGER的DIGITS转换标量是一个10位字符串,而BIGINT是一个19位字符串。这些列需要定义为DEC(6)或NUMERIC(6)。此外,如果即使使用TIME数据,也可以认为适用于所暗示的目的 - 这将是一个很难卖的;例如'时间('00010101'concat digits(start_time))' – CRPence 2016-09-24 20:51:37

2

你确定你需要转换吗?也许这个数字代表毫秒,所以差异会是4秒。

2

我建议值实际上意味着要一直小时八时59分58秒和9时00分01秒:分:秒猜测到底差为3

但这些都是你需要的所有猜测要求别人在你的公司他们是什么 - 因为别人可能用这些即使原来的编码器已经离开

+0

聪明! :) Arencha? – 2010-09-16 18:36:08

3

我测试了这个在MySQL,但我敢肯定,该技术可以适应在DB2工作:

SELECT 
    (end_time DIV 10000) * 3600 + 
    ((end_time DIV 100) % 100) * 60 + 
    end_time % 100 - 
    (start_time DIV 10000) * 3600 - 
    ((start_time DIV 100) % 100) * 60 - 
    start_time % 100 
FROM table1 

结果:

3 

它的工作方式是使用整数除法和模运算来提取每个时间戳的HH MM和SS部分并将每个部分转换为秒。然后将秒数加在一起以形成每个时间戳自午夜以来的总秒数。这两者之间的差异给交易时间。

请注意,如果事务在午夜之前开始并在午夜之后结束,则此操作将不起作用。您可能需要考虑一天是否发生了变化,并对此进行了更正。如果您没有将数据存储在数据库中,那么您可以查找负转换时间并添加24小时以使其为正,并且这应该给出正确的结果(只要交易的长度不超过一天,但是我猜这在实践中不太可能)。

我在写这篇用于DB2(未测试)的尝试:

SELECT 
    (end_time/10000) * 3600 + 
    MOD(end_time/100, 100) * 60 + 
    MOD(end_time, 100) - 
    (start_time/10000) * 3600 - 
    MOD(start_time/100, 100) * 60 - 
    MOD(start_time, 100) 
FROM table1 
+0

这听起来很有希望。很确定这会起作用。谢谢!当我有机会运行代码时,我会反馈。 – Codemwnci 2010-09-16 18:42:52

+0

@Codemwnci:从Google上看起来,当你编写'a/b'时,DB2似乎默认进行整数除法,而不是''a/b'做浮点除法的MySQL。这就是为什么我在MySQL中使用'DIV'而不是'/',但是您可能需要在DB2上使用'/'。抱歉,模糊,但我没有安装DB2,所以我无法测试它是肯定的。 – 2010-09-16 18:51:42

+0

@Codemwnci:我已经做了一些Google搜索,看起来不是'x%y',你需要使用'MOD(x,y)'函数。 – 2010-09-16 18:59:05

3

假设你正在使用DB2 for LUW中,你可以做到这一点使用的一些功能:

  • 数字() - 给你一个零填充整数的字符串
  • TRANSLATE() - 重新设置字符串的格式
  • MIDNIGHT_SECONDS - 返回自午夜以来的秒数。

这将适用于值为100 = '00:01:00'的情况。

实施例:

select 
    id, 
    MIDNIGHT_SECONDS(TRANSLATE('EF:GH:IJ',DIGITS(end_time),'ABCDEFGHIJ')) - 
     MIDNIGHT_SECONDS(TRANSLATE('EF:GH:IJ',DIGITS(start_time),'ABCDEFGHIJ')) as runtime 
from 
    your_table; 

如果START_TIME> END_TIME(即,START_TIME是午夜之前,但END_TIME是午夜之后)上面表达式将不起作用。

当然,真正的问题在于使用INT来存储TIME。最好修正你的数据模型,以便使用TIME(或更好的是TIMESTAMP)。

+0

我试过这个解决方案,但不幸的是我使用iSeries DB2,并且翻译功能失败。我不得不使用子字符串和连接来产生翻译,然后解决方案奏效。 – Codemwnci 2010-09-17 09:35:22

+0

是的,使用“db2”标记帖子通常是不够的。您需要说明您正在运行的平台,因为DB2 LUW,zSeries上的DB2和iSeries上的DB2之间存在一些差异。 – 2010-09-18 05:46:30