我有一个工作日志表。我想知道每台服务器 2 小时内每分钟运行多少个作业。
我知道我可以用 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
最佳答案
如果您每次执行作业时在作业表中记录足够的数据(包括确切的时间),您的答案将是在表中进行选择并每分钟对作业进行分组。我不熟悉 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
...
如果您对所有服务器执行此操作,那么您可以查询这个新的时态表以获取特定范围。这将为您提供每分钟在该日期范围内运行的作业的更准确结果。
关于php - 在一张表中收集多个计数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23086440/