加入的最大值 table 基于第一个 table 的值
Max from joined table based on value from first table
我有 2 个 tables。
第一个保存工作详细信息,第二个保存这些工作的历史 运行s。第一个还包含每个客户的工作周期,这是在 运行 为同一客户下一个工作之前等待的最短时间。时间比较需要在秒 table.
的 started_on
字段上进行
接下来我需要找到 运行 的工作 ID。
架构
- job_details table
CREATE TABLE `job_details` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`customer_id` varchar(128) NOT NULL,
`period_in_minutes` int(11) unsigned NOT NULL,
`status` enum('ACTIVE','INACTIVE','DELETED') DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
- job_run_history table
CREATE TABLE `job_run_history` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`job_id` int(10) unsigned NOT NULL,
`started_on` timestamp NULL DEFAULT NULL,
`status` enum('STREAMING','STREAMED','UPLOADING','UPLOADED','NO_RECORDS','FAILED') DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `fk_job_id` (`job_id`),
CONSTRAINT `fk_job_id` FOREIGN KEY (`job_id`) REFERENCES `job_details` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
job_detailstable的示例数据:
INSERT INTO `job_details` (`id`, `customer_id`, `period_in_minutes`, `status`)
VALUES
(1, 'cust1', 1, 'ACTIVE'),
(2, 'cust2', 1, 'ACTIVE'),
(3, 'cust3', 2, 'ACTIVE');
job_run_historytable的示例数据:
INSERT INTO `job_run_history`(`job_id`, `started_on`, `status`)
VALUES
(1, '2021-07-01 14:38:00', 'UPLOADED'),
(2, '2021-07-01 14:37:55', 'UPLOADED');
预期输出(当 运行 在 2021-07-01 14:38:56
时):
id
2,3
-
id => 1
未被选中,因为最后一个作业在最后 1 分钟内开始
-
id => 2
DID 被选中是因为最后一个作业开始时间超过 1 分钟前
-
id => 3
DID 被选中是因为它没有 运行 历史记录
我已经试过了,但是这不能与最大值 start_time
相比,因此,不起作用:
select jd.id, max(jrh.started_on) from job_details jd
left join job_run_history jrh on jrh.job_id=jd.id
where
jd.status='ACTIVE'
and (jrh.status is null or jrh.status not in ('STREAMING','STREAMED','UPLOADING'))
and (jrh.`started_on` is null or jrh.`started_on` < date_sub(now(), interval jd.`period_in_minutes`*60 second))
group by jd.id;
MySql版本:5.7.34
有什么帮助吗?提前致谢..
我更愿意使用 UNION ALL(它必须比一个复杂的查询更快):
-- the subquery for the rows which have matched ones in 2nd table
SELECT t1.id
FROM job_details t1
JOIN job_run_history t2 ON t1.id = t2.job_id
WHERE t1.status = 'ACTIVE'
AND t2.status not in ('STREAMING','STREAMED','UPLOADING')
AND CURRENT_TIMESTAMP - INTERVAL t1.period_in_minutes MINUTE > t2.started_on
UNION ALL
-- the subquery for the rows which have no matched ones in 2nd table
SELECT id
FROM job_details t1
WHERE NOT EXISTS ( SELECT NULL
FROM job_run_history t2
WHERE t1.id = t2.job_id )
AND status = 'ACTIVE';
https://dbfiddle.uk/?rdbms=mysql_5.7&fiddle=8dcad95bf43ce711fdf40deda627e879
select jd.id from job_details jd
left join job_run_history jrh on jd.id= jrh.job_id
where jd.status = 'ACTIVE'
group by jd.id
having
max(jrh.started_on) < current_timestamp - interval max(jd.period_in_minutes) minute
or
max(jrh.id) is null
我不确定这个过滤器是关于什么的,因为你没有在你的问题中解释它,所以我没有把它放在查询中:jrh.status not in ('STREAMING','STREAMED','UPLOADING')
。但是,我相信您可以在我发布的查询中实现它。
我有 2 个 tables。
第一个保存工作详细信息,第二个保存这些工作的历史 运行s。第一个还包含每个客户的工作周期,这是在 运行 为同一客户下一个工作之前等待的最短时间。时间比较需要在秒 table.
的started_on
字段上进行
接下来我需要找到 运行 的工作 ID。
架构
- job_details table
CREATE TABLE `job_details` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`customer_id` varchar(128) NOT NULL,
`period_in_minutes` int(11) unsigned NOT NULL,
`status` enum('ACTIVE','INACTIVE','DELETED') DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
- job_run_history table
CREATE TABLE `job_run_history` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`job_id` int(10) unsigned NOT NULL,
`started_on` timestamp NULL DEFAULT NULL,
`status` enum('STREAMING','STREAMED','UPLOADING','UPLOADED','NO_RECORDS','FAILED') DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `fk_job_id` (`job_id`),
CONSTRAINT `fk_job_id` FOREIGN KEY (`job_id`) REFERENCES `job_details` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
job_detailstable的示例数据:
INSERT INTO `job_details` (`id`, `customer_id`, `period_in_minutes`, `status`)
VALUES
(1, 'cust1', 1, 'ACTIVE'),
(2, 'cust2', 1, 'ACTIVE'),
(3, 'cust3', 2, 'ACTIVE');
job_run_historytable的示例数据:
INSERT INTO `job_run_history`(`job_id`, `started_on`, `status`)
VALUES
(1, '2021-07-01 14:38:00', 'UPLOADED'),
(2, '2021-07-01 14:37:55', 'UPLOADED');
预期输出(当 运行 在 2021-07-01 14:38:56
时):
id
2,3
-
id => 1
未被选中,因为最后一个作业在最后 1 分钟内开始
-
id => 2
DID 被选中是因为最后一个作业开始时间超过 1 分钟前
-
id => 3
DID 被选中是因为它没有 运行 历史记录
我已经试过了,但是这不能与最大值 start_time
相比,因此,不起作用:
select jd.id, max(jrh.started_on) from job_details jd
left join job_run_history jrh on jrh.job_id=jd.id
where
jd.status='ACTIVE'
and (jrh.status is null or jrh.status not in ('STREAMING','STREAMED','UPLOADING'))
and (jrh.`started_on` is null or jrh.`started_on` < date_sub(now(), interval jd.`period_in_minutes`*60 second))
group by jd.id;
MySql版本:5.7.34
有什么帮助吗?提前致谢..
我更愿意使用 UNION ALL(它必须比一个复杂的查询更快):
-- the subquery for the rows which have matched ones in 2nd table
SELECT t1.id
FROM job_details t1
JOIN job_run_history t2 ON t1.id = t2.job_id
WHERE t1.status = 'ACTIVE'
AND t2.status not in ('STREAMING','STREAMED','UPLOADING')
AND CURRENT_TIMESTAMP - INTERVAL t1.period_in_minutes MINUTE > t2.started_on
UNION ALL
-- the subquery for the rows which have no matched ones in 2nd table
SELECT id
FROM job_details t1
WHERE NOT EXISTS ( SELECT NULL
FROM job_run_history t2
WHERE t1.id = t2.job_id )
AND status = 'ACTIVE';
https://dbfiddle.uk/?rdbms=mysql_5.7&fiddle=8dcad95bf43ce711fdf40deda627e879
select jd.id from job_details jd
left join job_run_history jrh on jd.id= jrh.job_id
where jd.status = 'ACTIVE'
group by jd.id
having
max(jrh.started_on) < current_timestamp - interval max(jd.period_in_minutes) minute
or
max(jrh.id) is null
我不确定这个过滤器是关于什么的,因为你没有在你的问题中解释它,所以我没有把它放在查询中:jrh.status not in ('STREAMING','STREAMED','UPLOADING')
。但是,我相信您可以在我发布的查询中实现它。