php - 在一张表中收集多个计数

标签 php mysql sql perl

我有一个工作日志表。我想知道每台服务器 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/

相关文章:

php - 简化复杂的count SQL语句

javascript - 如何使用 jQuery 显示/隐藏复选框选中/未选中状态的元素

php - 合并 2 个 MySQL 数据库

php - 根据选定的数据库条目显示数据库中的数据

php - mysql中的变量类似语句

mysql - 无法从案例陈述中检索准确的结果

php - 检查 magento url 中的 UTM 标签

mysql - SQL - 最佳方式[期初期末余额]

sql - 如何用 SQL 连接 2 个以上的字段?

SQL语句根据同一个表的ID获取列