Mysql连接表最新记录的时间

时间:2016-09-24 12:15:53

标签: mysql database

你好我有以下两个表,它们代表一个带有阶段的文件和一个显示时间文件被移到下一阶段的历史表

CREATE TABLE `document` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `description` text,
  `stage` tinyint(4) NOT NULL DEFAULT '0',
  `customer_name` varchar(100) DEFAULT NULL,
  `creator_id` bigint(20) NOT NULL DEFAULT '0',
  `customer_city` varchar(100) DEFAULT NULL,
  `customer_state` varchar(100) DEFAULT NULL,
  `customer_zip` varchar(50) DEFAULT NULL,
  `customer_contact` varchar(100) DEFAULT NULL,
  `number` varchar(100) DEFAULT NULL,
  `latitude` float NOT NULL DEFAULT '0',
  `longitude` float NOT NULL DEFAULT '0',
  `creation_date` varchar(50) DEFAULT NULL,
  `expanded_description` text,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

CREATE TABLE IF NOT EXISTS `document_history` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `doc_id` bigint(20) NOT NULL,
  `modifying_time` datetime DEFAULT NULL,
  `changed_to_stage` tinyint(3) unsigned DEFAULT NULL,
  `old_stage` tinyint(3) unsigned DEFAULT NULL,
  `user_modified` bigint(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

我需要根据选定的时间段获取统计数据。例如,我需要知道在选定期间有多少文档在第1阶段,但问题是如果文档在此期间处于几个不同的阶段 - 我有只计算最后一个阶段,例如如果doc在第1阶段,在第2阶段之后 - 我只需要计算第2阶段。

这是我现在所拥有的:

SELECT 
round(sum(case when dh.modifying_time between '2016-09-15' and '2016-09-24' and dh.changed_to_stage = 1 then 1 else 0 end),0) entry_count,
round(sum(case when dh.modifying_time between '2016-09-15' and '2016-09-24' and dh.changed_to_stage = 3 then 1 else 0 end),0) pricing_count,
round(sum(case when dh.modifying_time between '2016-09-15' and '2016-09-24' and dh.changed_to_stage = 5 then 1 else 0 end),0) executed_count,
round(sum(case when dh.modifying_time between '2016-09-15' and '2016-09-24' and dh.changed_to_stage = 7 then 1 else 0 end),0) approved_count,
round(sum(case when dh.modifying_time between '2016-09-15' and '2016-09-24' and dh.changed_to_stage = 9 then 1 else 0 end),0) canceled_count
FROM document doc join document_history dh on doc.id=dh.doc_id 

这里的问题是,如果该文件在该期间处于两个不同的阶段,则会对该文件计数两次。

任何帮助将不胜感激。

谢谢和最好的问候

1 个答案:

答案 0 :(得分:1)

您只想选择 last 阶段,然后您可以在where中执行逻辑。但是,我建议先将日期条件移至WHERE并删除ROUND()(对于整数?真的吗?):

SELECT sum(case when dh.changed_to_stage = 1 then 1 else 0 end) as entry_count,
       sum(case when dh.changed_to_stage = 3 then 1 else 0 end) as pricing_count,
       sum(case when dh.changed_to_stage = 5 then 1 else 0 end) as executed_count,
       sum(case when dh.changed_to_stage = 7 then 1 else 0 end) as approved_count,
       sum(case when dh.changed_to_stage = 9 then 1 else 0 end) as canceled_count
FROM document doc join
     document_history dh
     on doc.id = dh.doc_id 
WHERE dh.modifying_time between '2016-09-15' and '2016-09-24' and
      dh.modifying_time = (SELECT MAX(dh2.modifying_time)
                           FROM document_history dh2
                           WHERE dh2.doc_id = dh.doc_id AND
                                 dh2.modifying_time between '2016-09-15' and '2016-09-24'
                          );

注意:

  • 不要将日期存储为字符串(例如creation_date)。
  • 您应该将between与日期或日期时间一起使用。你的表达可能不符合你的意图。把它写成dh.modifying_time >= '2016-09-15' and dh.modifying_time < '2016-09-25',这可能就是你想要的。
  • 如果您想保留所有文档,请使用left join代替inner join,并将where条件移至on条款。
  • round()有一个整数参数?我只是不明白那个。
  • 并且,如上所述,查询根本不需要document表,只需要document_history。您可以将from document_history视为简化。