2011-03-12 64 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在這裏,因爲現在我們需要連接起來將之前的數字轉換爲字符串。