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 |
+-----+---------------------+--------------+------------------+