这是给你的一个查询。它使用用户变量来表示查询范围的结束,但在最终版本中,您可能更愿意使用参数占位符。请注意,这是您查询的范围之后@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;
在SQL Fiddle上测试。不知道为什么所有的演员都是必要的,也许有一种方法可以避免其中的一些。但是上面的方法似乎有效,而一些演员阵容较少的版本则没有。
这个想法是子查询创建一个范围表,每个范围表示给定预算生效的日期。您可能需要调整第一个范围的开头,以匹配查询范围的开头。然后,您只需减去日期即可获得每个日期的天数,并将该数字乘以每日预算。