如何以时间格式检索两列之间的差异?

时间:2009-09-07 07:22:39

标签: sql

我有2列称为记录时间和卸载时间,时间格式为“AM / PM”,我需要一个名为总时间的新列来计算卸载时间和记录时间之间的差异......

例如,这是我的表:

record time                  unload time
11:37:05 PM                  11:39:09 PM
11:44:56 PM                    1:7:23 AM

我需要第三列,其中包含这两列之间的差异。它必须采用以下格式:“1:1:1”

对于上面的例子,我需要输出:

record time                  unload time         total time
11:37:05 PM                  11:39:09 PM         0:2:04
11:44:56 PM                    1:7:23 AM         1:22:27

如何编写查询来实现此目的?

7 个答案:

答案 0 :(得分:4)

取决于数据库。对于mysql非常简单:

select time(T1 - T2) from TABLE

对于另一个数据库可能会有点复杂。

答案 1 :(得分:3)

你真的不需要第三列,除非你真的想存储那个值。

无论如何,要获得价值:

SELECT TIMEDIFF(unload_time , record_time) AS dif FROM your_table LIMIT 1;

答案 2 :(得分:1)

我不知道mysql,但一般来说SQL应该类似于:

在查询中执行此操作

select unload_time - record_time as total_time 
from the_table

作为额外栏目

alter table the_table
 add column total_time time null;

update the table set total_time = unload_time - record_time;

答案 3 :(得分:0)

1)你真的需要分别存储差异吗?这是冗余数据。只有当您有一张大表并且需要定期报告时,才有理由这样做。在所有其他情况下,您可以动态计算差异。

2)如果需要这样做,请使用数据库触发器。由于您没有提到目标数据库平台,我只能给您一个通用的答案。您需要的是更新/插入后触发器,它将计算插入新记录或更新现有记录时的差异。

你如何计算差异?

如果您使用的是数据库提供的TIMSTAMP数据类型,那么计算差异非常容易。在Oracle中,如果两列都是TIMESTAMP数据类型,则可以通过减去两列来完成此操作。

请提供数据库信息以获取具体答案。

答案 4 :(得分:0)

对于MySQL:将您的时间与'1970-01-01'连接起来。你的时间应该是24小时格式。 因此:

的MySQL>选择TIMEDIFF('1970-01-01 14:45:05','1970-01-01 11:39:05');

+ ---------------------------------------------- ------------ +

| TIMEDIFF('1970-01-01 14:45:05','1970-01-01 11:39:05')|

+ ---------------------------------------------- ------------ +

| 03:06:00 |

+ ---------------------------------------------- ------------ +

它不支持AM / PM。 OR:

的MySQL>选择TIMEDIFF(CAST('1970-01-01 11:45:05 PM'AS DATETIME),CAST('1970-01-01 11:50:05 PM'AS DATETIME));

+ ---------------------------------------------- -------------------------------------------------- ------- +

| TIMEDIFF(CAST('1970-01-01 11:45:05 PM'AS DATETIME),CAST('1970-01-01 11:50:05 PM'AS DATETIME))|

+ ---------------------------------------------- -------------------------------------------------- ------- +

| -00:05:00
|

+ ---------------------------------------------- -------------------------------------------------- ------- +

建议以24小时格式存储时间。 否则,请研究DATE_FORMAT函数文档。

答案 5 :(得分:0)

数据模型完全是怪人。您只存储时间元素,而不是24小时制,并依赖于每列中PM和AM的比较,以避免产生垃圾结果。这假设您跟踪的过程不会运行24小时或更长时间。此外,生成的列将采用显示格式,而不是更有用的内容,例如总经过的秒数。

但是,作为一个有趣的午餐时间挑战,无论如何我决定对它进行破解。您尚未指定数据库,因此我使用的是Oracle。

此函数接受两个字符串,将它们转换为时间戳,计算它们之间的间隔,最后返回所需格式的字符串:

SQL> create or replace function calc_diff
  2      (t1 in load_times.record_time%type
  3       , t2 in load_times.upload_time%type)
  4      return varchar2
  5      deterministic
  6  as
  7      l_t1 timestamp;
  8      l_t2 timestamp;
  9      diff INTERVAL DAY (0) TO SECOND (0);
 10      return_value varchar2(8);
 11  begin
 12      l_t1 := to_date('01/01/2000 '||t1, 'dd/mm/yyyy hh:mi:ss am');
 13      l_t2 := to_date('01/01/2000 '||t2, 'dd/mm/yyyy hh:mi:ss am');
 14      --
 15      --  allow for processes which run over midnight
 16      --
 17      if l_t2 < l_t1
 18      then
 19          l_t2 := l_t2 + INTERVAL '1' DAY;
 20      end if;
 21      --
 22      -- calculate the interval between the two times
 23      --
 24      diff := to_dsinterval(l_t2- l_t1);
 25      --
 26      --  format the return value to exclude the unwanted day and fractional second elements
 27      --
 28      return_value := lpad( extract (hour from diff), 2, '0')
 29                      ||':'||lpad( extract (minute from diff), 2, '0')
 30                      ||':'||lpad(trunc(extract (second from diff)), 2, '0') ;
 31      return return_value;
 32  end;
 33  /

Function created.

SQL>
现在我们可以使用这个功能是一个很酷的新的Oracle 11g功能,虚拟列。这避免了触发器的需要。

SQL> alter table load_times
  2      add elapsed_time varchar2(8) GENERATED ALWAYS AS      
  3              (substr(calc_diff(record_time, upload_time),1,8)) VIRTUAL
  4  /

Table altered.

SQL> select * from load_times
  2  /

RECORD_TIME UPLOAD_TIME ELAPSED_
----------- ----------- --------
11:37:05 PM 11:39:09 PM 00:02:04
11:44:56 PM 1:7:23 AM   01:22:27

SQL>

不是这样,为了使其起作用,函数CALC_DIFF()必须标记为DETERMINISTIC。此外,虚拟列必须将SUBSTR()应用于函数的输出,因为我们在声明函数时无法约束它。

答案 6 :(得分:0)

我最终使用了以下

$submittime = date( 'Y-m-d H:i:s', strtotime(get_time()));
$starttime = date( 'Y-m-d H:i:s', strtotime($_POST["starttime"]));