MySql按日期范围获取总和
以下是一些用于存储广告活动预算历史记录的表格: 活动(预算)(历史)MySql按日期范围获取总和,mysql,Mysql,以下是一些用于存储广告活动预算历史记录的表格: 活动(预算)(历史) id_campaign budget date 1 10 2013-01-01 1 15 2013-01-03 1 10 2013-01-05 如果某个日期没有数据,它将等于上一次设定的预算 如何按日期范围计算预算总额,例如从“2013-01-02”到“2013-01-06”。结果必须是60美元,因为“2013-01-02”的预算将等
id_campaign budget date
1 10 2013-01-01
1 15 2013-01-03
1 10 2013-01-05
如果某个日期没有数据,它将等于上一次设定的预算
如何按日期范围计算预算总额,例如从“2013-01-02”到“2013-01-06”。结果必须是60美元,因为“2013-01-02”的预算将等于“2013-01-01”,而“2013-01-04”的预算将等于“2013-01-03”
有什么办法可以通过SQL实现吗?这里有一个查询。它使用用户变量来表示查询范围的结束,但在最终版本中,您可能更愿意使用参数占位符。请注意,@end是您查询范围后的第一天,也就是说,它是该范围的独占端
SET @begin = '2013-01-02';
SET @end = '2013-01-07';
SELECT
SUM(DATEDIFF(IF(CAST(c.end AS date) > CAST(@end AS date),
CAST(@end AS date),
CAST(c.end AS date)
),
IF(c.begin < CAST(@begin AS date),
CAST(@begin AS date),
c.begin
)
) * c.budget
) AS overall_budget
FROM
(SELECT a.id_campaign,
a.date begin,
MIN(IFNULL(b.date, CAST(@end AS date))) end,
a.budget
FROM campaign_budgets_history a
LEFT JOIN campaign_budgets_history b
ON a.id_campaign = b.id_campaign AND a.date < b.date
WHERE a.date < CAST(@end AS date)
GROUP BY a.id_campaign, a.date
HAVING end > CAST(@begin AS date)
) c;
经过测试。不确定为什么所有的演员阵容看起来都是必要的,也许有一种方法可以避免其中的一些。但上述方法似乎有效,而一些较少强制转换的版本则没有
其思想是子查询创建一个范围表,每个范围表示给定预算生效的日期。您可能需要调整第一个范围的开头,以匹配查询范围的开头。然后,您只需减去日期即可获得每个日期的天数,并将该天数乘以每日预算。此示例使用日历实用程序表
SELECT * FROM calendar WHERE dt BETWEEN '2012-12-27' AND '2013-01-12';
+------------+
| dt |
+------------+
| 2012-12-27 |
| 2012-12-28 |
| 2012-12-29 |
| 2012-12-30 |
| 2012-12-31 |
| 2013-01-01 |
| 2013-01-02 |
| 2013-01-03 |
| 2013-01-04 |
| 2013-01-05 |
| 2013-01-06 |
| 2013-01-07 |
| 2013-01-08 |
| 2013-01-09 |
| 2013-01-10 |
| 2013-01-11 |
| 2013-01-12 |
+------------+
SELECT SUM(budget) total
FROM campaign_budgets_history a
JOIN
( SELECT MAX(y.date) max_date
FROM calendar x
JOIN campaign_budgets_history y
ON y.date <= x.dt
WHERE x.dt BETWEEN '2013-01-02' AND '2013-01-06'
GROUP
BY x.dt
) b
ON b.max_date = a.date;
最简单的方法是构造一个包含所有可能日期的日历表,然后将您的表加入其中。您需要遵循@草莓的建议:SUM用于聚合现有数据,因此有必要创建汇总所需的缺失行数据。@草莓,即使有日期表,您仍然需要找到要为每个日期应用的数据行,这意味着您必须确定日期范围之类的内容。一旦你有了这样的范围,拥有所有日期的表格就变得非常多余了。详细信息请参见我的答案。@MvG您的查询非常聪明,我猜也非常有效。我只是提倡一种更简单的方法,见下文