Mysql加入时间匹配

时间:2011-03-12 16:41:45

标签: mysql join

我有两个表cpuinfo和jobinfo。我想使用两种数据创建报告。

脊髓痨;

CREATE TABLE `cpuinfo` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `usagetime` datetime DEFAULT NULL,
  `cpuusage` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `id_UNIQUE` (`id`)

CREATE TABLE `jobinfo` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `starttime` datetime NOT NULL,
  `endtime` datetime DEFAULT NULL,
  `jobname` text NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `id_UNIQUE` (`id`)

值:

cpuinfo
id,usagetime,cpuusage
1,"2011-03-12 11:10:01",40
2,"2011-03-12 11:10:31",45
3,"2011-03-12 11:11:01",45
4,"2011-03-12 11:11:31",43
5,"2011-03-12 11:12:01",55
6,"2011-03-12 11:12:31",49

jobinfo
id,starttime,endtime,jobname
1,"2011-03-12 11:10:01","2011-03-12 11:10:08","job a"
2,"2011-03-12 11:10:05","2011-03-12 11:10:18","job b"
3,"2011-03-12 11:10:15","2011-03-12 11:10:28","job c"
4,"2011-03-12 11:10:31","2011-03-12 11:10:38","job d"
5,"2011-03-12 11:10:45","2011-03-12 11:10:48","job e"
6,"2011-03-12 11:10:55","2011-03-12 11:10:55","job f"
7,"2011-03-12 11:11:31","2011-03-12 11:11:43","job d"
8,"2011-03-12 11:11:45","2011-03-12 11:11:49","job e"
9,"2011-03-12 11:11:55","2011-03-12 11:11:59","job f"
10,"2011-03-12 11:12:31","2011-03-12 11:12:43","job d"
11,"2011-03-12 11:12:45","2011-03-12 11:12:49","job e"
12,"2011-03-12 11:12:55","2011-03-12 11:12:59","job f"

我正在寻找这样的输出:

starttime,endtime,jobname,cpuusage
"2011-03-12 11:10:01","2011-03-12 11:10:08","job a",40
"2011-03-12 11:10:05","2011-03-12 11:10:18","job b",40
"2011-03-12 11:10:15","2011-03-12 11:10:28","job c",40
"2011-03-12 11:10:31","2011-03-12 11:10:38","job d",45
"2011-03-12 11:10:45","2011-03-12 11:10:48","job e",45
"2011-03-12 11:10:55","2011-03-12 11:10:55","job f",45
"2011-03-12 11:11:31","2011-03-12 11:11:43","job d",43
"2011-03-12 11:11:45","2011-03-12 11:11:49","job e",43
"2011-03-12 11:11:55","2011-03-12 11:11:59","job f",43
"2011-03-12 11:12:31","2011-03-12 11:12:43","job d",49
"2011-03-12 11:12:45","2011-03-12 11:12:49","job e",49
"2011-03-12 11:12:55","2011-03-12 11:12:59","job f",49

此SQL将不匹配的sql值赋予null

select a.starttime, a.endtime, a.jobname,b.cpuusage  from jobinfo a
    left join cpuinfo b on b.usagetime >= a.starttime and  b.usagetime <= a.endtime 

基本上我想在那个工作时间列出所有工作和相应的cpuusage。

由于 SR

2 个答案:

答案 0 :(得分:0)

试试这个:

SELECT j.id, j.starttime, j.endtime, j.jobname, c.cpuusage
FROM
(
    SELECT j.id, j.starttime, j.endtime, j.jobname, MAX(c.usagetime) AS usagetime
    FROM jobinfo AS j
    LEFT JOIN cpuinfo AS c
    ON c.usagetime <= j.starttime
    GROUP BY j.id
) AS j
JOIN cpuinfo AS c
ON j.usagetime = c.usagetime

这提供了您想要的输出。它在每个作业的开始时间之前找到cpuusage的最新值。它在作业运行时不处理cpuusage的变化。

答案 1 :(得分:0)

如果您不希望结果集中包含NULL值,则可以省略包含NULL值的行。它可以通过使用INNER JOIN而不是LEFT JOIN来完成:

select a.starttime, a.endtime, a.jobname,b.cpuusage  from jobinfo a
  inner join cpuinfo b on b.usagetime >= a.starttime and  b.usagetime <= a.endtime

如果你不想省略任何行,那么你必须决定用什么代替NULL,并使用IFNULL。例如,如果要将所有NULL替换为0,则脚本将为:

select a.starttime, a.endtime, a.jobname, ifnull(b.cpuusage, 0) as cpuusage
from jobinfo a
  left join cpuinfo b on b.usagetime >= a.starttime and  b.usagetime <= a.endtime

您要求并且未澄清的另一件事是,您希望看到cpuinfo中有多行与jobinfo中的行匹配的结果。< / p>

一种方法是简单地输出所有匹配项,因此如果一个作业有多个CPU事件,它将被相应地列出多次。

如果这不合适,您只能选择一个值,例如最新的值,如@Mark Byers提议的那样。但在这种情况下,某些CPU事件可能最终被排除在结果集之外。

这是一个简单的说明:

         |CPU1                  |CPU2               |CPU3   
+--------+------+------+-------+------+-----------+-+------+-------
|Astart           |Aend   |Bstart          |Cstart         |Bend   |Cend

B作业期间,有两个事件,CPU 2 和CPU 3 。后者也是C工作期间发生的唯一事件。如果我们只选择每个作业的最新事件,那么CPU 2 将不会使其成为结果,因为它只发生在一个作业中,而不是最近的作业。< / p>

包含所有事件而不复制作业的解决方案可能是将一列中的所有事件作为值列表输出。这可以在GROUP_CONCAT

的帮助下解决
select
  a.starttime, a.endtime, a.jobname,
  group_concat(convert(ifnull(b.cpuusage, 0), char) separator ',') as cpuusage
from jobinfo a
  left join cpuinfo b on b.usagetime >= a.starttime and  b.usagetime <= a.endtime

正如您所看到的,我们也在这里使用CONVERT,因为现在我们需要在连接之前将数字转换为字符串。