SQL查询可在给定的时间点生成正在进行的工作

时间:2018-07-15 06:34:02

标签: mysql sql

我有一个项目管理数据库,我正试图为其构建一个SQL查询,该查询将在给定的时间点生成给定用户正在进行的工作的最新估计。

进行中的工作定义为一项任务,在给定的时间,它的最新任务历史记录是其中状态列为以下值之一的一项:12,13,14,15

下面提供了结构和数据集的摘录。

对于此数据集,适用以下情形:

场景1

  • 输入参数:
    • 用户ID:1
    • 时间点:2018-01-01
  • 应返回ID为1的估算值条目
    • 乐观:5,现实10,悲观:20

场景2

  • 输入参数:
    • 用户ID:1
    • 时间点:2017年1月1日
  • 应返回ID为4的估算条目
    • 乐观:2,现实:4,悲观:6

场景3

  • 输入参数
    • 用户ID:1
    • 时间点:2017-06-01
  • 不应返回任何条目-当前用户1尚无任何作品

方案4

  • 输入参数
    • 用户ID:2
    • 时间点:2017年1月1日
  • 不应返回任何条目-当前(或与此相关的任何其他时间),用户2正在进行任何工作

此查询的复杂性超出了我通常必须处理的SQL方式。因此,我正在寻找有关如何构造查询的建议。请告知我是否应该在其他地方请求此类帮助。

# Dump of table estimate
# ------------------------------------------------------------

DROP TABLE IF EXISTS `estimate`;

CREATE TABLE `estimate` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `task_id` int(11) DEFAULT NULL,
  `optimistic` float DEFAULT NULL,
  `realistic` float DEFAULT NULL,
  `pessimistic` float DEFAULT NULL,
  `created` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

LOCK TABLES `estimate` WRITE;
/*!40000 ALTER TABLE `estimate` DISABLE KEYS */;

INSERT INTO `estimate` (`id`, `task_id`, `optimistic`, `realistic`, `pessimistic`, `created`)
VALUES
    (1,1,5,10,20,'2017-10-01 00:00:00'),
    (2,1,10,20,30,'2018-02-01 00:00:00'),
    (3,2,1,2,3,'2016-10-01 00:00:00'),
    (4,2,2,4,6,'2016-11-01 00:00:00'),
    (5,2,3,6,0,'2017-01-01 00:00:00');

/*!40000 ALTER TABLE `estimate` ENABLE KEYS */;
UNLOCK TABLES;


# Dump of table task
# ------------------------------------------------------------

DROP TABLE IF EXISTS `task`;

CREATE TABLE `task` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `user_id` int(11) DEFAULT NULL,
  `name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

LOCK TABLES `task` WRITE;
/*!40000 ALTER TABLE `task` DISABLE KEYS */;

INSERT INTO `task` (`id`, `user_id`, `name`)
VALUES
    (1,1,'WIP 2018-01-01'),
    (2,1,'WIP 2017-01-01');

/*!40000 ALTER TABLE `task` ENABLE KEYS */;
UNLOCK TABLES;


# Dump of table task_history
# ------------------------------------------------------------

DROP TABLE IF EXISTS `task_history`;

CREATE TABLE `task_history` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `task_id` int(11) DEFAULT NULL,
  `status` int(11) DEFAULT NULL,
  `timestamp` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

LOCK TABLES `task_history` WRITE;
/*!40000 ALTER TABLE `task_history` DISABLE KEYS */;

INSERT INTO `task_history` (`id`, `task_id`, `status`, `timestamp`)
VALUES
    (1,1,10,'2017-10-01 00:00:00'),
    (2,1,12,'2017-12-01 00:00:00'),
    (3,1,1,'2018-01-03 00:00:00'),
    (4,2,10,'2016-10-01 00:00:00'),
    (5,2,14,'2016-12-01 00:00:00'),
    (6,2,1,'2017-02-01 00:00:00');

/*!40000 ALTER TABLE `task_history` ENABLE KEYS */;
UNLOCK TABLES;


# Dump of table user
# ------------------------------------------------------------

DROP TABLE IF EXISTS `user`;

CREATE TABLE `user` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

LOCK TABLES `user` WRITE;
/*!40000 ALTER TABLE `user` DISABLE KEYS */;

INSERT INTO `user` (`id`, `name`)
VALUES
    (1,'User 1'),
    (2,'User 2');

/*!40000 ALTER TABLE `user` ENABLE KEYS */;
UNLOCK TABLES;

2 个答案:

答案 0 :(得分:0)

SELECT *
FROM Estimate, TaskHistory
WHERE Estimate.task_id = TaskHistory.task_id
AND status IN (12,13,14,15);

这应该选择其对应TaskHistory状态为12、13、14或15的估算值。

答案 1 :(得分:0)

以下查询获取给定时间点@timestamp之前每个用户的每个任务的最新任务历史记录。

然后,它仅返回具有您感兴趣的状态的行。

select th.*
from task_history th join
     task t
     on th.task_id = t.task_id
where th.timestamp = (select max(th2.timestamp)
                      from task_history th2 join
                           task t2
                           on th2.task_id = t.task_id
                      where t2.assignee_id = t.assignee_id and
                            th2.timestamp <= @timestamp
                     ) and
      th.status in (12, 13, 14, 15);

我怀疑您想要其他过滤(针对特定用户)或聚合。您不清楚结果集应该是什么样子。