我真的不确定如何标题这个问题,很抱歉......
我有一个网站,用户可以观看"产品。当他们开始观看产品时,会在product_tracking
中插入一行,如下所示:
+-----------------------+------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------------+------------+------+-----+---------+----------------+
| id | bigint(11) | NO | PRI | NULL | auto_increment |
| u_id | int(11) | NO | MUL | NULL | |
| p_id | bigint(11) | NO | MUL | NULL | |
| date_started_tracking | datetime | NO | | NULL | |
| date_stopped_tracking | datetime | YES | | NULL | |
+-----------------------+------------+------+-----+---------+----------------+
用户开始观看插入行时date_started_tracking
插入产品的日期时间,默认情况下date_stopped_tracking
为null
。当用户停止观看产品时,date_stopped_tracking
将使用当前日期时间进行更新。
我希望在我的网站上有一个图表,显示随时间推移跟踪的产品数量。像这样:
# tracks
| __/
| ___ /
| / \__/
| /
| /
| ____/
| /
| ___/
| /
|/___________________________ date (grouped by day, week, or month)
我不知道如何编写查询来检索制作图表所需的信息。
难以理解的是,我希望按天,周或月对行进行分组,但如果date_started_tracking
为< =分组日期且,则只包含组中的行date_stopped_tracking
为null
或>分组日期(即选择显示在该日期被跟踪的产品的行)。
换句话说,对于每天,每周或每月(取决于所需的粒度),应返回当时用户正在观看的产品数量。
我尝试解决方案
我提出的唯一想法是创建一个日期表,然后编写一个查询,例如:
SELECT WEEK(d.date) as week,
(SELECT COUNT(pt.id)
FROM product_tracking pt
WHERE pt.date_started_tracking <= d.date AND (pt.date_stopped_tracking IS NULL OR pt.date_stopped_tracking > d.date)
) as numWatches
FROM dates d
GROUP BY week
ORDER BY week ASC
我认为这样可行,但需要创建一个日期表,这似乎有点迟钝。
有更好的方法吗?
答案 0 :(得分:0)
您的方法有效,但无法很好地扩展。另一种方法是使用累积和的变量逐日跟踪跟踪。这看起来像:
select dte, sum(inc) as net,
(@sum := @sum + sum(inc)) as total_for_day
from ((select date_start_tracking as dte, count(*) as inc
from product_tracking
group by date_start_tracking
) union all
(select date_stopped_tracking, - count(*)
from product_tracking
where date_stopped_tracking is not null
group by date_stopped_tracking
)
) pt cross join
(select @sum := 0) vars
group by dte
order by dte;
这是解决方案的概要。对于您的数据,您可能需要一个超过停止日期 - 取决于该产品是否在当天计算。
然后,您可以将此查询用作子查询,以便在您喜欢的任何时间段进行聚合。