我有一份工作日志表。我想知道每台服务器上每小时运行的作业数量是多少。
我知道我可以用PHP或PERL来做这件事。是否有纯SQL方法来完成此任务?
我相信我需要做一个while循环,以日期/时间变量和整数变量为最大分钟。可以在sql语句中完成while循环,还是需要存储过程?
这是我写过的存储过程。我知道它还没有存储任何数据。
当我尝试运行时,MySQL抱怨没有选择数据库:
DELIMITER //
CREATE PROCEDURE `StatsByMinute`(IN StartDate datetime,
IN NumMin integer,
IN WSServer varchar(16))
BEGIN
DECLARE c INT;
SET c = -1;
WHILE c <= NumMin DO
SELECT COUNT(*)
FROM tws.SymphonyJobs
WHERE JobStarted <= TIMESTAMPADD(MINUTE,1+c,StartDate)
AND JobCompleted >= TIMESTAMPADD(MINUTE,2+c,StartDate)
AND JobWS= WSServer;
SET c=c+1;
END WHILE;
END
任何帮助都将不胜感激。
示例数据:
StreamWS JobStarted JobCompleted
Server1 4/12/2014 21:31 4/12/2014 21:53
Server1 4/12/2014 21:31 4/12/2014 21:53
Server1 4/12/2014 21:31 4/12/2014 21:53
Server1 4/12/2014 21:31 4/12/2014 21:53
Server1 4/12/2014 21:31 4/12/2014 21:53
Server1 4/12/2014 21:31 4/12/2014 21:53
Server1 4/12/2014 21:31 4/12/2014 21:53
Server1 4/12/2014 21:31 4/12/2014 21:53
Server2 4/13/2014 0:01 4/13/2014 0:03
Server2 4/13/2014 0:01 4/13/2014 0:03
Server2 4/13/2014 0:01 4/13/2014 0:03
Server2 4/13/2014 0:01 4/13/2014 0:03
Server2 4/13/2014 0:01 4/13/2014 3:28
Server2 4/13/2014 0:02 4/13/2014 0:03
Server2 4/13/2014 0:02 4/13/2014 0:03
Server2 4/13/2014 0:02 4/13/2014 0:03
Server2 4/13/2014 0:02 4/13/2014 0:03
Server2 4/13/2014 0:02 4/13/2014 0:03
Server2 4/13/2014 0:02 4/13/2014 0:03
Server2 4/13/2014 0:02 4/13/2014 0:03
答案 0 :(得分:0)
如果您在每次作业执行时都在作业表中记录了足够的数据,包括准确的计时,您的答案就是在表格中进行选择并按分钟对作业进行分组。我不熟悉MySQL,但我可以在SQL Server中向您展示一个可以完成这项工作的简单选择:
SELECT DATEPART(MINUTE,YourDate), Count(YourJob)
FROM #X
GROUP BY DATEPART(MINUTE,YourDate), YourJob
DATEPART是SQL Server中的一个函数,它可以获取日期的特定部分(在本例中为分钟)。您可能在MySQL中找到类似的功能?然后,您只需使用此功能分组您的行,然后按作业计数。这将显示每分钟完成的工作数。
更新:在MySQL中试试这个:
SELECT MINUTE(YourDate), Count(YourJob)
FROM #X
GROUP BY MINUTE(YourDate), YourJob
更新2:希望这对您更有效...
SELECT StreamWS, DATEFORMAT(JobStarted,'%d %m %y %H') as Date, MINUTE(JobStarted) StartedMinute,
Count(StreamWS) Total
FROM #YourTable
WHERE STR_TO_DATE(JobStarted, '%d/%m/%Y') BETWEEN '01-Jan-2013' AND '01-Jun-2015'
GROUP BY StreamWS, DATEFORMAT(JobStarted,'%d %m %y'), MINUTE(JobStarted)
在此查询中,您首先按服务器进行分组,以便您能够查看每个服务器的结果,然后查看实际发生的日期(您可以在此处更改参数,以便您可以像你需要,例如每小时,或每天,或每个月,然后每分钟分割每分钟的计数。在Where子句中,您可以添加所需的日期范围。
有关MySQL中日期操作的更多信息: http://dev.mysql.com/doc/refman/5.0/en/date-and-time-functions.html#function_date-format
更新3:
我正在考虑解决这个问题的另一个选择是递归CTE,但经过一些研究后我发现MySQL并不支持它们(https://dba.stackexchange.com/questions/46061/mysql-equivalent-of-with-in-oracle),我会告诉你它是怎么样的(我虽然没有测试它,所以你可以用不同的方式做同样的事情......
WITH X (StreamWS, MyCount, [Minutes]) AS
(
SELECT StreamWS, 1 as MyCount, DATEDIFF(MINUTE,JobStarted,JobCompleted) FROM #TransactionLog T
UNION ALL
SELECT X.StreamWS, X.MyCount+1, X.Minutes-1 FROM X
WHERE X.Minutes>0 and X.MyCount<X.Minutes
--JOIN #TransactionLog T ON X.StreamWS = T.StreamWS
--AND DATEDIFF(MINUTE,T.JobStarted,T.JobCompleted)<X.MyCount<
)
SELECT * FROM X
这个想法是复制它运行的每一分钟的条目(作业),例如对于样本表中的服务器1,你运行22分钟(从21:31到21:53):你可以有一个新的时态表,其中Server1被创建为每分钟一行(即22次):
StreamWS MyCount Time
-------- ----------- -----------
Server1 1 4/12/2014 21:31
Server1 2 4/12/2014 21:32
Server1 3 4/12/2014 21:33
Server1 4 4/12/2014 21:34
...
如果对所有服务器执行此操作,则可以查询此新时间表以查找特定范围。这应该可以为您提供更准确的作业结果,即每分钟在该日期范围内运行的作业。