2011-03-12 68 views
2

我有两个表cpuinfo和jobinfo。我想使用这两个数据创建报告。Mysql加入时间匹配

tabes;

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 

基本上我想列出所有工作和通讯在这段工作时间内完成工作。

感谢 SR

+1

当您在该作业时间之间没有任何cpu使用情况时,您会期望什么?如果你在这个工作期间有多个cpuusage呢? – 2011-03-12 16:51:51

+0

我们从vmstat输出中导入,我们会有这个值。如果时间不可用,我可以使用以前的值。如果我有多个,我可以使用最后一个。 – sfgroups 2011-03-12 21:23:47

回答

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中的更改。

+0

它给了我想要的结果,但是当在每个表上加载4000条记录时,它需要10分钟才能完成。 – sfgroups 2011-03-12 21:49:39

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为那。例如,如果你想替换所有0的NULL,你的脚本是:

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中的一行。

一种方法可能是简单地输出所有的匹配项,所以如果一项工作有多个CPU事件,它会相应地多次列出。

如果这不合适,您可以选择一个值,例如最近的一个值,如@Mark Byers正在提出。但是在这种情况下,一些CPU事件可能最终被排除在结果集之外。

这里有一个简单的例子:

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

B工作有两个事件,CPU 和CPU 。后者也是在C工作期间发生的唯一事件。如果我们仅为每项工作选择最近的事件,那么CPU 将不会达到结果,因为它只发生在一项工作中,并不是最新的工作。

将包含所有事件而不复制作业的解决方案可能是将一列中的所有事件作为值列表输出。这可能与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在这里,因为现在我们需要连接起来将之前的数字转换为字符串。