mysql只统计最近7天的数据,最近7天的MySQL计数数据

本文介绍了如何使用MySQL查询在不支持递归的情况下,通过创建临时表(numbers)获取过去7天内每个aid每天的投票次数,特别关注了包含零投票的情况。作者提到了利用日期差和INCREMENTING numbers技巧来实现日期范围内的计数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

I have the following schema.

Table votes

+------------------+--------------+------+-----+---------------------+----------------+

| Field | Type | Null | Key | Default | Extra |

+------------------+--------------+------+-----+---------------------+----------------+

| id | int(10) | NO | PRI | NULL | auto_increment |

| aid | varchar(10) | NO | | | |

| ip | varchar(100) | NO | | | |

| host | varchar(200) | NO | | | |

| timestamp | varchar(20) | NO | | 0000-00-00 00:00:00 | |

| user | tinytext | NO | | NULL | |

| userid | int(10) | NO | | 0 | |

+------------------+--------------+------+-----+---------------------+----------------+

Here I want to get the count of each aid on a day for the last 7 days with "0"s for the dates where there a no votes for aid. timestamp is unix timestamp here.

Any help is highly appreciated.

解决方案

MySQL doesn't have recursive functionality, so you're left with using the NUMBERS table trick -

Create a table that only holds incrementing numbers - easy to do using an auto_increment:

DROP TABLE IF EXISTS `example`.`numbers`;

CREATE TABLE `example`.`numbers` (

`id` int(10) unsigned NOT NULL auto_increment,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Populate the table using:

INSERT INTO NUMBERS

(id)

VALUES

(NULL)

...for as many values as you need.

Use DATE_ADD to construct a list of dates, increasing the days based on the NUMBERS.id value. Replace "2010-01-01" and "2010-01-02" with your respective start and end dates (but use the same format, YYYY-MM-DD HH:MM:SS). In this example, I subtracted the NUMBERS.id value from the CURRENT_DATE to get a list of sequential date values for the last week -

SELECT x.dt

FROM (SELECT DATE_SUB(CURRENT_DATE, INTERVAL (n.id - 1) DAY) AS dt

FROM numbers n

WHERE n.id <= 7 ) x

LEFT JOIN onto your table of data based on the datetime portion.

SELECT x.dt,

COUNT(v.aid) AS num

FROM (SELECT DATE_SUB(CURRENT_DATE, INTERVAL (n.id - 1) DAY) AS dt

FROM numbers n

WHERE n.id <= 7 ) x

LEFT JOIN VOTES v ON DATE(FROM_UNIXTIME(v.timestamp)) = DATE(x.dt)

GROUP BY x.dt

ORDER BY x.dt

Why Numbers, not Dates?

Simple - dates can be generated based on the number, like in the example I provided. It also means using a single table, vs say one per data type.

Previously:

SELECT DATE(FROM_UNIXTIME(v.timestamp)) AS dt,

COUNT(v.aid)

FROM VOTES v

WHERE DATE(FROM_UNIXTIME(v.timestamp)) BETWEEN DATE_SUB(CURRENT_DATE, INTERVAL 7 DAY)

AND CURRENT_DATE

GROUP BY DATE(FROM_UNIXTIME(v.timestamp))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值