我有2个表,一个是InvoiceFull,另一个是TestInvoiceFull

在我的基于php和mysql的Web应用程序中,每小时记录100条记录到InvoiceFull中。
我需要在MySQL中创建一个事件,以每小时获取5条记录,并从InvoiceFull提取权重的1/4,并将这些记录插入TestInvoiceFull。 TestInvoiceFull是我的存档表。

我写了如下查询,每小时插入1条记录,但我每小时需要5条记录。

INSERT INTO TestInvoiceFull (Weight,Status,StatusChangedTime)
SELECT a.Weight/4 AS ApprovedWeight,
       a.Status,
       a.StatusChangedTime
FROM InvoiceFull a
INNER JOIN
  (SELECT DATE(StatusChangedTime) date, HOUR(StatusChangedTime) hour,
                                        MIN(StatusChangedTime) min_date
   FROM InvoiceFull
   WHERE status='Approved'
   GROUP BY DATE(StatusChangedTime),
            HOUR(StatusChangedTime)) b ON DATE(a.StatusChangedTime) = b.date
AND HOUR(a.StatusChangedTime) = b.hour
AND a.StatusChangedTime = b.min_date;


我在小时组中选择了最短时间,因此每小时仅提取1行。如何每小时获取5条记录或一般情况下N条记录。

提前致谢。

最佳答案

您的要求是:


随机选择的记录...
从前一个小时开始...
插入修改内容...
按日期时间升序编辑。


让我们一次使用这些。要随机选择五个记录,您需要

SELECT whatever
  FROM table
 ORDER BY RAND()
 LIMIT 5


速度不是很快,但是可以正常工作。

其次,您需要在前一个小时使用StatusChangedTime来选择记录。为此,您需要一种获取当前时间开始的方法。

STR_TO_DATE(NOW(), '%Y-%m-%d %H:00:00')


做到这一点。它花费时间NOW(),并将分钟和秒更改为零。我们可以使用相同的想法来开始上一个小时的开始:

STR_TO_DATE(NOW(), '%Y-%m-%d %H:00:00') - INTERVAL 1 HOUR


因此,让我们在WHERE子句中使用这些表达式。

SELECT whatever
  FROM InvoiceFull a
 WHERE a.StatusChangedTime >= STR_TO_DATE(NOW(), '%Y-%m-%d %H:00:00') - INTERVAL 1 HOUR
   AND a.StatusChangedTime  < STR_TO_DATE(NOW(), '%Y-%m-%d %H:00:00')


这将选择从上一行的开头开始的所有行,直到(但不包括)当前小时的开头。

接下来,您需要修改结果集中的列之一。您正确地做到了。如果Weight列是浮点值,则可能应使用Weight * 0.25而不是除法。

INSERT INTO TestInvoiceFull
       (Weight,Status,StatusChangedTime)
SELECT (a.Weight * 0.25) AS ApprovedWeight,
       a.Status,
       a.StatusChangedTime  ...


最后,您希望按日期时间戳按顺序随机抽取五个记录。因此,将您的基本SELECT查询放入子查询中...

INSERT INTO TestInvoiceFull
       (Weight,Status,StatusChangedTime)
SELECT *
  FROM (
  SELECT (a.Weight * 0.25) AS ApprovedWeight,
         a.Status,
         a.StatusChangedTime
    FROM InvoiceFull a
   WHERE a.StatusChangedTime >= STR_TO_DATE(NOW(), '%Y-%m-%d %H:00:00') - INTERVAL 1 HOUR
     AND a.StatusChangedTime  < STR_TO_DATE(NOW(), '%Y-%m-%d %H:00:00')
   ORDER BY RAND()
   LIMIT 5
  ) b ORDER BY StatusChangedTime


按日期顺序有五个随机记录。每小时在某个时间运行一次,您将获得过去一小时记录的样本。为了获得最好的结果,我每小时要等到五点或十分钟,以防万一系统的某些部分落后了。

请注意,您在问题中的查询中误用了GROUP BYGROUP BY仅在使用诸如SUM()之类的聚合操作时对您有帮助。

10-04 10:54