【问题标题】:How to query one random row, prioritizing last 6 hours?如何查询一个随机行,优先考虑最后 6 小时?
【发布时间】:2023-03-09 15:26:01
【问题描述】:

我有一个名为 adverts 的表,我从中提取随机记录

SELECT date, body FROM adverts ORDER BY rand()

使用记录 date 字段,我如何才能优先提取过去 6 小时内添加的随机记录。我想拉一条记录

如果最近六个小时内没有条目,则将搜索范围扩大到 12、18 等

有什么简洁的方法可以做到这一点?使用 PHP 和 mySQL

【问题讨论】:

  • 需要返回多少行?
  • 首先分享您的SHOW CREATE TABLE adverts 和一些示例数据..
  • 因此,如果在过去 6 小时内找到了一条记录,那么您就不需要其他任何记录,如果在过去 6 小时内没有找到任何记录,那么即使是 100 条记录,您也需要过去 12 年的所有记录?
  • 我只想随时拉一张唱片。如果在过去 6 小时内没有添加任何内容,则将搜索范围扩大到 12 小时。使用 PHP 和 MySQL

标签: php mysql random


【解决方案1】:

如果没有更多信息,假设您使用的是MySQL,一个很好的方法是创建一个包含现在和您的时间变量之间的最小距离的variable, 然后,选择与此时间对应的所有内容。

您甚至可以选择变量来了解当前时间与您的最短时间之间已经过去了多少小时。

set @hours = (select min(hours) from (select TIMESTAMPDIFF(HOUR, 
your_time_variable,
curdate()) as hours from adverts) t);


SELECT * FROM adverts
WHERE (TIMESTAMPDIFF(HOUR, your_time_variable, curdate())) = @hours
ORDER BY rand();

您可以自定义这些以过滤您想要的内容。

【讨论】:

    【解决方案2】:

    我怀疑是否值得在一个查询中执行此操作。使用ORDER BY RAND() 选择随机行的方法总是非常昂贵,因此多次运行它不是一个好主意。

    这是另一种策略:找出确实有数据的最近时间窗口。

    SELECT CEILING(TIMESTAMPDIFF(HOUR, MAX(date), NOW()) / 6) * 6 FROM adverts;
    

    例如,我测试了使用 9 小时前的时间戳向表中添加一行。上面的查询返回 12。

    mysql> SELECT TIMESTAMPDIFF(HOUR, MAX(date), NOW()) FROM adverts;
    +---------------------------------------+
    | TIMESTAMPDIFF(HOUR, MAX(date), NOW()) |
    +---------------------------------------+
    |                                     9 |
    +---------------------------------------+
    
    mysql> SELECT CEILING(TIMESTAMPDIFF(HOUR, MAX(date), NOW())/6)*6 FROM adverts;
    +----------------------------------------------------+
    | CEILING(TIMESTAMPDIFF(HOUR, MAX(date), NOW())/6)*6 |
    +----------------------------------------------------+
    |                                                 12 |
    +----------------------------------------------------+
    

    这样您就可以知道用于随机选择查询的最佳时间长度:

    SELECT date, body FROM adverts WHERE date >= NOW() - INTERVAL 12 HOUR
    ORDER BY RAND() LIMIT 1;
    

    【讨论】:

      【解决方案3】:

      你可以写一个存储过程来处理逻辑:

      DELIMITER $$
      CREATE PROCEDURE fetchSample(
      IN limit_size INT)
      BEGIN
          DECLARE x  INT;
          DECLARE y  INT;
      
          SET x = 0;
          SET y = 0;
      
          WHILE x  <= 4 AND y = 0 DO
      
              SET  x = x + 1; 
              SET  y = (SELECT count(*) FROM adverts WHERE  yourDateTimeField BETWEEN 
              NOW() - INTERVAL CONVERT(6 * x, CHAR) HOUR AND NOW() ORDER BY rand()
              LIMIT limit_size);
      
          END WHILE;
      
          SELECT * FROM adverts WHERE  yourDateTimeField BETWEEN 
          NOW() - INTERVAL CONVERT(6 * x, CHAR) HOUR AND NOW() ORDER BY rand() 
          LIMIT limit_size;
      
      END$$
      DELIMITER ;
      

      【讨论】:

      • 我没有投反对票,但 OP 并没有说他们使用的是编程语言(如 Java 或 PHP)。 OP 可能需要 1 个查询来返回他们需要的数据。
      • @isaace 我刚刚更新了我的答案。他可以用存储过程来做逻辑。
      猜你喜欢
      • 1970-01-01
      • 2019-09-20
      • 1970-01-01
      • 2021-07-13
      • 1970-01-01
      • 1970-01-01
      • 2011-03-09
      • 1970-01-01
      • 2020-05-27
      相关资源
      最近更新 更多