【问题标题】:Complex MySQL Timer复杂的 MySQL 计时器
【发布时间】:2009-10-10 15:32:18
【问题描述】:

如果我们有一个从 CURRENT_TIMESTAMP - 1 小时开始的计时器,我们可以简单地计算差值并返回 3600 秒过去。

但是,如果我们希望计时器只在一天中的特定时间计数,并且只在工作日或指定日期工作,该怎么办。查看下面的代码以查看 Create 语句以更好地理解

CREATE TABLE `timer` (
  `Id`             BIGINT        NOT NULL  AUTO_INCREMENT,
  `title`          VARCHAR(100)  NOT NULL,
  `startAt`        DATETIME      NOT NULL,

  `startTime`      TIME                    DEFAULT NULL,
  `endTime`        TIME                    DEFAULT NULL,

  `monday`         BOOLEAN                 DEFAULT 1,
  `tuesday`        BOOLEAN                 DEFAULT 1,
  `wednesday`      BOOLEAN                 DEFAULT 1,
  `thursday`       BOOLEAN                 DEFAULT 1,
  `friday`         BOOLEAN                 DEFAULT 1,
  `saturday`       BOOLEAN                 DEFAULT 1,
  `sunday`         BOOLEAN                 DEFAULT 1,

  `dateReg`        TIMESTAMP     NOT NULL  DEFAULT CURRENT_TIMESTAMP,

  PRIMARY KEY  (`Id`)

) ENGINE=InnoDB AUTO_INCREMENT=1  COMMENT 'Timer';

Note: The startime and endtime represent the hours the timer will take into account when counting seconds from two dates. The timer as represented above does not have a endtime meaning it will never stop

现在有人说它可以在查询中完成,我相信他们是对的,但我个人相信在存储函数中它会更容易更好:

CREATE FUNCTION `TIMEPASSED`(iId BIGINT(100)) RETURNS BIGINT(20)
BEGIN
    DECLARE sTime TIME;
    DECLARE eTime TIME;
    DECLARE startAt DATETIME;

    #Get the Results from the Database and put them into the variables
    SELECT timer.startTime, timer.endTime, timer.startAt INTO sTime, eTime, startAt FROM tickets
    WHERE timer.Id = iId;

    #if the start time is null then return the difference between the reset time and now
    IF sTime IS NULL
       THEN RETURN (UNIX_TIMESTAMP(CURRENT_TIMESTAMP) - UNIX_TIMESTAMP(startAt));
    END IF;

RETURN NULL;

END

如果startTime 为空,则上述函数仅返回自定时器启动以来经过的完整秒数。

现在让我们进行插入查询

INSERT INTO timer VALUES(NULL, 'mytimer', CURRENT_TIMESTAMP, 09:00, 18:00, 1, 1, 1, 1, 1, 0, 0, CURRENT_TIMESTAMP);

上述查询表明计时器从 CURRENT_TIME 开始,仅在 09:00 到 18:00 之间计算秒数,并且仅适用于周一至周五。

SELECT 查询,(Order By 在这里很重要)

SELECT *, TIMEPASSED(Id) as passed FROM timer ORDER BY passed DESC

一般情况下:我想知道在输入的时间分配的时间内经过的秒数

任何对本学科基础数学的参考将不胜感激。那我就可以解决了

谢谢:D

【问题讨论】:

  • 仅供参考:在 SELECT 子句中调用相关函数可能会对性能产生不良影响 - 数据库将为返回的每一行调用该函数。
  • @rexem:哦,对不起,rexem,我明白你的意思了。对不起,不清楚:开始时间和结束时间代表每天计算的时间。它不代表计时器将停止的时间。计时器永远不会停止
  • 如果我理解了这个问题,您不只是输入开始时间,然后从 NOW() 函数中减去它以获取过去的时间吗?您也可以将时间格式化为任何格式吗? SELECT (UNIX_TIMESTAMP(CURRENT_TIMESTAMP) - UNIX_TIMESTAMP(startAt)) AS lapsedTime FROM ...
  • @Phil:如果你有一个简单的计时器来计算两个日期......我想做的是计算在星期一和星期二的 09:00 和 18:00 之间省略其余的日子。如果这有什么好笑的?

标签: sql mysql datetime


【解决方案1】:

如果我理解正确,我认为在您的存储过程中使用的一个好的算法是:

  1. 从零开始计数。
  2. 如果今天与 dateReg 是同一日期,并且对应的星期几为真,则将 max(startTime, dateReg's time) - min(endTime, current time) 添加到计数中。
  3. 否则,如果今天在 dateReg 日期之后:
    1. 如果 dateReg 对应的星期几为真,并且 dateReg 的时间在 endTime 之前,则将 max(startTime, dateReg 的时间) - endTime 添加到计数中。
    2. 如果今天对应的星期几为真,并且当前时间在 startTime 之后,则将 startTime - min(endTime, current time) 添加到计数中。
  4. 将 endTime - startTime 存储在 wholeDay 中。
  5. 如果 monday 为真,则计算 dateReg 的日期和当前日期之间的星期一数,不包括。* 将该数字乘以 WholeDay 的结果添加到计数中。一周中的每一天都重复一遍。
  6. 返回计数。

* 这本身就是另一个问题。一种方法是计算 dateReg 的一周之后和当前周之前的完整周数,然后如果 dateReg 的 DoW 之后的一天(星期几)在所讨论的 DoW 之前,则加 1,如果当前 DoW 的前一天在相关 DoW 之后。

【讨论】:

  • @Kev:你在正确的轨道上:D...我几乎在 MySQL 中完成了一个可行的解决方案,我将在赏金结束时发布它...就像我想要的那样得到它:D
  • BAecause of your concept..我有完全相同的概念我会接受:D
猜你喜欢
  • 2014-12-28
  • 1970-01-01
  • 2016-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-25
  • 2021-03-03
相关资源
最近更新 更多