php - 具有一个值和另一个值的记录之间的 TIMEDIFF(),而不仅仅是一个

标签 php mysql sql date-math

我有一个记录项目状态的表:

CREATE TABLE `project_states` (
    `id` INT(10) NOT NULL AUTO_INCREMENT,
    `state_id` INT(10) NULL DEFAULT NULL,
    `project_id` INT(10) NULL DEFAULT NULL,
    `created_at` TIMESTAMP NULL DEFAULT NULL,
    PRIMARY KEY (`id`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB

一些假数据:

    id  | state_id | project_id | created_at
-----------------------------------------------------
     1  |   2      |   8        | 2014-05-27 10:58:12   
     2  |   3      |   8        | 2014-05-27 11:10:34
     3  |   8      |   8        | 2014-05-27 11:56:48
     4  |   2      |  10        | 2014-05-27 11:08:34
     5  |   4      |  10        | 2014-05-27 11:59:01

我正在尝试获取两个状态(比如 2 和 8)之间的时差,并且只针对那些确实有两个状态的项目;在这种情况下,仅适用于项目 8(因为 10 没有状态 8)。

到目前为止,我已经成功地选择了符合条件的项目(有两个值,而不仅仅是一个),但是这个查询为每个匹配的项目返回一个结果元组:

SELECT t.*
   FROM (
     SELECT ps.*
     FROM project_states ps
     WHERE ps.state_id IN (2,8) 
   ) as t
JOIN project_states pro ON pro.project_id = t.project_id
WHERE pro.state_id = 8

正确返回:

    id  | state_id | project_id | created_at
-----------------------------------------------------
     1  |   2      |   8        | 2014-05-27 10:58:12   
     3  |   8      |   8        | 2014-05-27 11:56:48

我很确定它可以工作,因为如果我将缺失的状态添加到另一个项目,它会返回新的结果元组:

    id  | state_id | project_id | created_at
-----------------------------------------------------
     1  |   2      |   8        | 2014-05-27 10:58:12   
     3  |   8      |   8        | 2014-05-27 11:56:48
     4  |   2      |  10        | 2014-05-27 11:08:34
     6  |   8      |  10        | 2014-05-27 12:03:08

但是如何计算时差呢?我正在使用 PHP,我知道我可以通过 project_id 遍历结果并然后计算差异,但我认为可能有一个纯 SQL 解决方案会产生如下结果:

project_id | difference
------------------------
     8     | 0000-00-00 01:02:00
    10     | 0000-00-00 01:05:26

嗯,实际上我的目标是计算项目位于这两个选定状态之间的平均时间差,因此所有记录都可以归结为一个平均值,但这可能是我后来发现的问题。

最佳答案

如果您只有 2 个状态,您可以使用简单的 INNER JOIN。和 TIMESTAMPDIFF()例如,以分钟为单位获得差异:

SELECT p.project_id,
       TIMESTAMPDIFF(MINUTE,p.created_at,p1.created_at) 
          as state_minutes_diff

FROM project_states as p
JOIN project_states as p1 
  ON p.project_id=p1.project_id
     AND p1.state_id=8  

WHERE p.state_id=3

SQLFiddle demo

获取所有项目的平均值:

SELECT AVG(TIMESTAMPDIFF(MINUTE,p.created_at,p1.created_at))
          as AVG_state_minutes_diff
FROM project_states as p
JOIN project_states as p1 
  ON p.project_id=p1.project_id
     AND p1.state_id=8  
WHERE p.state_id=3

SQLFiddle demo

关于php - 具有一个值和另一个值的记录之间的 TIMEDIFF(),而不仅仅是一个,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23890763/

相关文章:

mysql - 使用索引优化带有 ORDER BY 的 SELECT 语句

mysql - 如果字段 "post_title"在另一行中重复,如何删除表行?

php - 通过从表中传递多个分隔的逗号 id 获取记录,其中 id 在 mysql 表中也是逗号分隔的

mysql - 递归运行 MySQL 函数

php - 从 PHP 访问 JavaScript 变量

php - MYSQL中如何从一列中获取两个单词

java - hibernate - 从查询结果返回插入脚本

sql - Rownum 子句之间不起作用 - Oracle

php - 以半小时为增量创建选择列表

php - 使用 php 语法在 mysql 中创建新数据库