Mysql присоединиться с сопоставлением времени - PullRequest
2 голосов
/ 12 марта 2011

У меня есть две таблицы cpuinfo и jobinfo.Я хочу создать отчет, используя обе данные.

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 для нуля

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

Ответы [ 2 ]

0 голосов
/ 12 марта 2011

Если вам не нужны значения 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.

Одним из способов может быть просто вывести все совпадения, и поэтому, если задание имеет несколько событий ЦП, это будетперечислены более одного раза соответственно.

Если это не подходит, вы можете выбрать только одно значение, например, самое последнее, например, которое предлагает @ Mark Byers .Но в этом случае некоторые события ЦП могут остаться за пределами набора результатов.

Вот простая иллюстрация:

         |CPU<sub>1   </sub>               |CPU<sub>2   </sub>            |CPU<sub>3   </sub>
+--------+------+------+-------+------+-----------+-+------+-------
|A<sub>start   </sub>        |A<sub>end </sub>  |B<sub>start   </sub>       |C<sub>start   </sub>      |B<sub>end </sub>  |C<sub>end</sub>

Во время задания B было два события, ЦП 2 и процессор 3 .Последнее также было единственным событием, которое произошло во время работы C.Если бы мы выбрали только самые последние события для каждой работы, то CPU 2 не добрался бы до результатов, потому что это произошло только во время одной работы и не было самой последней для него.

Решение, которое будет включать все события без дублирования заданий, может заключаться в выводе всех событий в одном столбце в виде списка значений.Это можно решить с помощью 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, потому что теперь нам нужно преобразовать числа в строки перед их объединением.

0 голосов
/ 12 марта 2011

Попробуйте это:

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 во время выполнения задания.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...