【发布时间】:2020-01-09 11:05:06
【问题描述】:
我有一个记录在表格中的“开始/停止”活动列表,每个活动都与一个日期相关联。我需要确定哪些用户在特定日期“开始” - 即正在进行任务。我当前的设置和查询可以用这个简单的视图来表示:
CREATE TABLE `registration_statuses` (
`status_id` INT(11) NOT NULL AUTO_INCREMENT,
`status_user_id` INT(10) UNSIGNED NOT NULL DEFAULT '0',
`status_activity` ENUM('start','stop') DEFAULT 'start',
`status_date` DATE NULL DEFAULT NULL,
PRIMARY KEY (`status_id`),
INDEX `status_user_id` (`status_user_id`)
);
INSERT INTO `registration_statuses` (`status_user_id`, `status_activity`, `status_date`)
VALUES (1, 'start', '2020-01-01'),
(2, 'start', '2020-01-02'),
(1, 'stop', '2020-01-19'),
(1, 'start', '2020-01-25'),
(2, 'stop', '2020-01-31'),
(1, 'stop', '2020-01-31');
然后我运行这个查询:
SELECT `rs`.`status_user_id`
FROM `registration_statuses` `rs`
INNER JOIN (
SELECT `status_user_id`, MAX(status_date) `last_date`
FROM `registration_statuses`
WHERE `status_date` < '2020-01-03'
GROUP BY `status_user_id`
) `srs` ON `rs`.`status_user_id` = `srs`.`status_user_id`
AND `rs`.`status_date` = `srs`.`last_date`
WHERE `status_activity` = 'start';
(见http://sqlfiddle.com/#!9/c8d371/1/0)
通过更改查询中的日期,此查询会返回一个用户 ID 列表,告诉我谁在该特定日期参与(即已开始一项任务)。但是,用户被认为(在现实生活中)在他们停止任务的实际日期参与了任务。此查询不允许这样做,因为如果您要更改查询中的日期以反映 2020-01-19,即用户 1 停止的那一天,则查询将仅返回用户 2。
我尝试将<= 条件更改为严格的<,虽然这解决了部分问题,但用户在开始的那天并不被认为是忙碌的。使用严格的<,仅在“2019-01-25”返回用户,而我希望两个用户都出现。
在这一点上,我唯一“可行”的解决方案是合并两个版本查询的结果(以DISTINCT / UNION 查询的形式),但我不禁想到必须有一种更有效的方法来获得我需要的结果。
【问题讨论】:
-
到目前为止做得很好,但是在提供示例数据集时,包含将从所需结果中排除的数据通常会很有帮助。而且,澄清一下,我认为您希望用户在 2020 年 1 月 19 日之前参与了一项任务?
-
@Strawberry 嗨-我想我有...例如,如果您在 1 月 20 日查看,则应排除用户 1。我误会你了吗?
标签: mysql sql temporal-database