Mysql 每周查询数据库

Mysql 每周查询数据库,mysql,datetime,Mysql,Datetime,我有一个数据库,在列中创建了一个,其中包含Y-m-d H:I:s格式的日期时间 最新的日期时间条目是2011-09-28 00:10:02 我需要查询与最新的datetime条目相关 查询中的第一个值应该是最新的datetime条目 查询中的第二个值应该是距离第一个值最接近7天的条目 第三个值应该是距离第二个值最近的7天的条目 重复#3 我所说的“离……最近7天”是什么意思: 以下是日期,我希望的时间间隔是一周,以秒为单位的时间间隔是604800秒 从第一个值开始的7天等于1316578202(

我有一个数据库,在列中创建了一个
,其中包含
Y-m-d H:I:s
格式的日期时间

最新的日期时间条目是
2011-09-28 00:10:02

我需要查询与最新的datetime条目相关

  • 查询中的第一个值应该是最新的datetime条目
  • 查询中的第二个值应该是距离第一个值最接近7天的条目
  • 第三个值应该是距离第二个值最近的7天的条目
  • 重复#3
  • 我所说的“离……最近7天”是什么意思:

    以下是日期,我希望的时间间隔是一周,以秒为单位的时间间隔是604800秒

    从第一个值开始的7天等于1316578202(1317183002-604800)

    最接近1316578202(7天)的值为。。。1316571974

    unix timestamp | Y-m-d H:i:s
    
    1317183002 | 2011-09-28 00:10:02 -> appear in query (first value)
    1317101233 | 2011-09-27 01:27:13
    1317009182 | 2011-09-25 23:53:02
    1316916554 | 2011-09-24 22:09:14
    1316836656 | 2011-09-23 23:57:36
    1316745220 | 2011-09-22 22:33:40
    1316659915 | 2011-09-21 22:51:55
    1316571974 | 2011-09-20 22:26:14 -> closest to 7 days from 1317183002 (first value)
    1316499187 | 2011-09-20 02:13:07
    1316064243 | 2011-09-15 01:24:03
    1315967707 | 2011-09-13 22:35:07 -> closest to 7 days from 1316571974 (second value)
    1315881414 | 2011-09-12 22:36:54
    1315794048 | 2011-09-11 22:20:48
    1315715786 | 2011-09-11 00:36:26
    1315622142 | 2011-09-09 22:35:42
    
    我真的很感谢任何帮助,我还没有通过mysql做到这一点,而且似乎没有在线资源处理像这样的相对日期操纵。我希望查询足够模块化,能够每周、每月或每年更改间隔。提前谢谢

    答复#1答复:

    返回:

    unix_timestamp | random_1 | random_2
    1317183002 | 1317183002 | 1317183002
    
    答复#2答复:

    结果集:

    这是一个年度间隔的结果集:

    id  | created_at          | period_index | period_timestamp
    267 | 2010-09-27 22:57:05 | 0            | 1317183002
    1   | 2009-12-10 15:08:00 | 1            | 1285554786
    
    我希望得到这样的结果:

    id  | created_at          | period_index | period_timestamp
    626 | 2011-09-28 00:10:02 | 0            | 0
    267 | 2010-09-27 22:57:05 | 1            | 1317183002
    

    我希望这更有意义。

    如果你愿意在本周结束后进行最接近的训练,那么这就行了。你可以把它延伸到最接近的地方,但它看起来很恶心,可能不值得

    select unix_timestamp
         , ( select min(unix_tstamp)
               from my_table
              where sql_tstamp >= ( select max(sql_tstamp) - 7
                                      from my_table )
                    ) 
        , ( select min(unix_tstamp)
               from my_table
              where sql_tstamp >= ( select max(sql_tstamp) - 14
                                      from my_table )
                    )
      from my_table
     where sql_tstamp = ( select max(sql_tstamp)
                            from my_table )
    

    这不完全是您所要求的,但下面的示例非常接近

    例1:

    select
      floor(timestampdiff(SECOND, tbl.time, most_recent.time)/604800) as period_index, 
      unix_timestamp(max(tbl.time)) as period_timestamp
    from
      tbl
      , (select max(time) as time from tbl) most_recent
    group by period_index
    
    给出了以下结果:

    +--------------+------------------+
    | period_index | period_timestamp |
    +--------------+------------------+
    |            0 |       1317183002 | 
    |            1 |       1316571974 | 
    |            2 |       1315967707 | 
    +--------------+------------------+
    
    这会根据“周期”将数据集分成若干组,其中(在本例中)每个周期为7天(604800秒)。为每个时段返回的
    period\u timestamp
    是该时段内的“最新”(最近)时间戳

    周期边界都是根据数据库中最近的时间戳计算的,而不是根据之前周期的时间戳分别计算每个周期的开始和结束时间。区别很微妙——您的问题要求后者(迭代方法),但我希望前者(我在这里描述的方法)能够满足您的需要,因为SQL本身不适合实现迭代算法


    如果您确实需要根据前一个周期中的时间戳来确定每个周期,那么最好的选择是迭代方法——或者使用您选择的编程语言(如php),或者通过构建使用游标的存储过程


    编辑#1

    下面是上面示例的表结构

    CREATE TABLE `tbl` (
      `id` int(10) unsigned NOT NULL auto_increment PRIMARY KEY,
      `time` datetime NOT NULL
    ) 
    

    编辑#2

    好的,首先:我改进了原始的示例查询(参见上面修订的“示例1”)。它仍然以同样的方式工作,并给出同样的结果,但它更干净、更高效,更容易理解

    现在。。。上面的查询是一个分组查询,这意味着它显示了如上所述的“期间”组的聚合结果,而不是像“正常”查询那样的逐行结果。对于GROUPBY查询,只能使用聚合列。聚合列是在
    group by
    子句中命名的列,或由聚合函数(如
    MAX(time)
    )计算的列。无法从group by查询的投影中为非聚合列(如
    id
    )提取有意义的值

    不幸的是,当您尝试这样做时,mysql不会生成错误。相反,它只是从分组行中随机选取一个值,并在分组结果中为非聚合列显示该值。这就是OP在尝试使用示例1中的代码时报告的奇怪行为的原因

    幸运的是,这个问题很容易解决。只需围绕组查询包装另一个查询,以逐行选择您感兴趣的信息

    例2:

    SELECT 
      entries.id, 
      entries.time, 
      periods.idx as period_index, 
      unix_timestamp(periods.time) as period_timestamp
    FROM 
      tbl entries
    JOIN
      (select
         floor(timestampdiff( SECOND, tbl.time, most_recent.time)/31536000) as idx, 
         max(tbl.time) as time
       from
         tbl
         , (select max(time) as time from tbl) most_recent
       group by idx
      ) periods
    ON entries.time = periods.time
    
    结果:

    +-----+---------------------+--------------+------------------+
    | id  | time                | period_index | period_timestamp |
    +-----+---------------------+--------------+------------------+
    | 598 | 2011-09-28 04:10:02 |            0 |       1317183002 | 
    | 996 | 2010-09-27 22:57:05 |            1 |       1285628225 | 
    +-----+---------------------+--------------+------------------+
    
    注:

    • 示例2使用的周期长度为31536000秒(365天)。而示例1(上文)使用的时间段为
      604800秒
      (7天)。除此之外,示例2中的内部查询与示例1中显示的主查询相同

    • 如果匹配的时段时间属于多个条目(即,两个或多个条目具有完全相同的时间,并且该时间与所选时段时间值之一匹配),则上述查询(示例2)将包括给定时段时间戳的多行(每个匹配一行)。任何使用此结果集的代码都应该准备好处理这种边缘情况

    • 还值得注意的是,如果在datetime列上定义索引,这些查询将执行得非常非常好。对于我的示例模式,它如下所示:

      ALTER TABLE tbl ADD INDEX idx\u time(时间)


    我更新了我的问题,以回应您的回答,包括我的备选版本的查询及其返回的结果。它不能工作,至少我希望它能工作。这太棒了,真的谢谢你。它们有两个问题,它返回每个查询的第一个条目(id=1),而不是返回最新的条目。除此之外,到目前为止,这项工作非常有效。@ThomasReggi-你能更准确地描述这些问题吗?我不明白你所说的“每次查询都返回第一个条目(id=1),而不是返回最新条目”是什么意思。我在问题帖子底部有一个更详细的解释。@ThomasReggi-谢谢你提供的信息。我已经更新了上面的帖子(请参见“编辑#2”)。示例2-应该提供您想要的内容。非常感谢。我自己永远也不会明白这一点,我将学习这一点,以便能够理解每个部分!
    +-----+---------------------+--------------+------------------+
    | id  | time                | period_index | period_timestamp |
    +-----+---------------------+--------------+------------------+
    | 598 | 2011-09-28 04:10:02 |            0 |       1317183002 | 
    | 996 | 2010-09-27 22:57:05 |            1 |       1285628225 | 
    +-----+---------------------+--------------+------------------+