希望有人能够帮助我。
假设我有下面列出的表格。主机可以在同一天出现多次,通常使用不同的备份。
+------------------+--------------+
| Field | Type |
+------------------+--------------+
| startdate | date |
| host | varchar(255) |
| backupsize | float(6,2) |
+------------------+--------------+
我怎样才能找到7天增量从最早的日期开始到最后一个日期的备份总和?我不介意过去几天是否被切断,因为它们没有达到7天的增量。
期望的输出(首选):
+------------+----------+----------+----------+-----
|Week of | system01 | system02 | system03 | ...
+------------+----------+----------+----------+-----
| 2014/07/30 | 2343.23 | 232.34 | 989.34 |
+------------+----------+----------+----------+-----
| 2014/08/06 | 2334.7 | 874.13 | 234.90 |
+------------+----------+----------+----------+-----
| ... | ... | ... | ... |
OR
+------------+------------+------------+------
|Host | 2014/07/30 | 2014/08/06 | ...
+------------+------------+------------+------
| system01 | 2343.23 | 2334.7 | ...
+------------+------------+------------+-------
| system02 | 232.34 | 874.13 | ...
+------------+------------+------------+-------
| system03 | 989.34 | 234.90 | ...
+------------+------------+------------+-------
| ... | ... | ... |
日期格式不是问题,只要它以某种方式被识别。此外,主机的顺序也不是问题。谢谢!
答案 0 :(得分:3)
最简单的方法是获取最早的日期并计算天数:
select x.minsd + interval floor(datediff(x.minsd, lb.startdate) / 7) day as `Week of`,
host,
sum(backupsize)
from listedbelow lb cross join
(select min(startdate) as minsd from listedbelow lb) x
group by floor(datediff(x.minsd, lb.startdate) / 7)
order by 1;
这会在每行上生成一个week of
和host
的表单。您可以根据需要调整结果。
答案 1 :(得分:0)
我假设您想要的是bakcupsize
按host
分组的总和以及您正在谈论的七天间隔。
我的解决方案是这样的:
我认为临时表和带有临时变量的小技巧是解决这个问题的最佳方法,所以:
drop table if exists temp_data;
create temporary table temp_data
select a.*
-- The @d variable will have the date that you'll use later to group the data.
, @d := case
-- If the current "host" value is the same as the previous one, then...
when @host_prev = host then
-- ... if @d is not null and is within the seven-day period,
-- then leave the value of @d intact; in other case, add 7 days to it.
case
when @d is not null or a.startdate <= @d then @d
-- The coalesce() function will return the first not null argument
-- (just as a precaution)
else dateadd(coalesce(@d, a.startdate), interval +7 day)
end
-- If the current "host" value is not the same as the previous one,
-- then take the current date (the first date of the "new" host) and add
-- seven days to it.
else @d = dateadd(a.startdate, interval +7 day)
end as date_group
-- This is needed to perform the comparisson in the "case" piece above
, @host_prev := a.host as host2
from
(select @host_prev = '', @d = null) as init -- Initialize the variables
, yourtable as a
-- IMPORTANT: This will only work if you order the data properly
order by a.host, a.startdate;
-- Add indexes to the temp table, to make things faster
alter table temp_data
add index h(host),
add index dg(date_group)
-- OPTIONAL: You can drop the "host2" column (it is no longer needed)
-- , drop column host2
;
现在,您可以获取分组数据:
select a.host, a.date_group, sum(a.bakcupsize) as backupsize
from temp_data as a
group by a.host, a.date_group;
这将为您提供不透明的数据。如果您想使用它构建数据透视表,我建议您查看this article和/或read this question and its answers。简而言之,你必须建立一个动态的&#34; sql指令,用它准备一个语句并执行它。
当然,如果你想按周分组,那么这是一个更简单的方法:
drop table if exists temp_data2;
create temporary table temp_data2
select a.*
-- The following will give you the end-of-week date
, dateadd(a.startdate, interval +(6 - weekday(a.startdate)) day) as group_date
from yourtable as a;
alter table temp_data
add index h(host),
add index dg(date_group);
select a.host, a.date_group, sum(a.bakcupsize) as backupsize
from temp_data as a
group by a.host, a.date_group;
我将枢轴部分留给你。
答案 2 :(得分:0)
因此,我能够使用我推荐的解决方案中的概念以及我在本网站上找到的其他一些解决方案,使用我创建的程序来确定符合我需求的解决方案。过程SUM以7天为增量以及进行转动。
DELIMITER $$
CREATE PROCEDURE `weekly_capacity_by_host`()
BEGIN
SELECT MIN(startdate) into @start_date FROM testtable;
SET @SQL = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'SUM(if(host=''',host,''', backupsize, 0)) as ''',host,''''
)
) INTO @SQL
FROM testtable;
SET @SQL = CONCAT('SELECT 1 + DATEDIFF(startdate, ''',@start_date,''') DIV 7 AS week_num
, ''',@start_date,''' + INTERVAL (DATEDIFF(startdate, ''',@start_date,''') DIV 7) WEEK AS week_start,
', @SQL,'
FROM testtable group by week_num'
);
PREPARE stmt FROM @SQL;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END$$
DELIMITER ;
输出如下:
mysql> call weekly_capacity_by_host;
+----------+------------+----------+----------+----------+----------+
| week_num | week_start | server01 | server02 | server03 | server04 |
+----------+------------+----------+----------+----------+----------+
| 1 | 2014-06-11 | 1231.08 | 37.30 | 12.04 | 68.17 |
| 2 | 2014-06-18 | 1230.98 | 37.30 | 11.76 | 68.13 |
| 3 | 2014-06-25 | 1243.12 | 37.30 | 8.85 | 68.59 |
| 4 | 2014-07-02 | 1234.73 | 37.30 | 11.77 | 67.80 |
| 5 | 2014-07-09 | 341.32 | 0.04 | 0.14 | 4.94 |
+----------+------------+----------+----------+----------+----------+
5 rows in set (0.03 sec)