你好我有以下两个表,它们代表一个带有阶段的文件和一个显示时间文件被移到下一阶段的历史表
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
这里的问题是,如果该文件在该期间处于两个不同的阶段,则会对该文件计数两次。
任何帮助将不胜感激。
谢谢和最好的问候
答案 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
视为简化。