以7天为增量对MySQL结果进行分组
希望有人能帮我 假设我有下面列出的表格。主机可以在同一日期出现多次,通常具有不同的备份以7天为增量对MySQL结果进行分组,mysql,Mysql,希望有人能帮我 假设我有下面列出的表格。主机可以在同一日期出现多次,通常具有不同的备份 +------------------+--------------+ | Field | Type | +------------------+--------------+ | startdate | date | | host | varchar(255) | | backupsize | flo
+------------------+--------------+
| Field | Type |
+------------------+--------------+
| startdate | date |
| host | varchar(255) |
| backupsize | float(6,2) |
+------------------+--------------+
我如何才能找到从最早日期开始到最后日期的7天增量备份的总和?我不介意最后几天是否被中断,因为它们不属于7天增量
期望输出(首选):
或
日期格式并不重要,只要能以某种方式识别就行。此外,主机的顺序也不重要。谢谢 最简单的方法是获取最早的日期,然后计算天数:
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;
这将生成一个表格,每行上有
周
和主机
。您可以根据自己的需要调整结果。最简单的方法是获得最早的日期,然后只计算天数:
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;
这将生成一个表格,每行上有
周
和主机
。您可以根据自己的需要调整结果。最简单的方法是获得最早的日期,然后只计算天数:
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;
这将生成一个表格,每行上有
周
和主机
。您可以根据自己的需要调整结果。最简单的方法是获得最早的日期,然后只计算天数:
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;
这将生成一个表格,每行上有
周
和主机
。您可以根据自己的需要调整结果。我假设您想要的是按主机分组的bakcupsize
和您所说的七天间隔的总和
我的解决方案是这样的:
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
;
这将为您提供未插入的数据。如果要使用它构建数据透视表,我建议您查看、和/或。简而言之,您必须构建一条“动态”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;
我把轴心部分留给你。我假设你想要的是
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
;
这将为您提供未插入的数据。如果要使用它构建数据透视表,我建议您查看、和/或。简而言之,您必须构建一条“动态”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;
我把轴心部分留给你。我假设你想要的是
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
;
这将为您提供未插入的数据。如果要使用它构建数据透视表,我建议您查看、和/或。简而言之,您必须构建一条“动态”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;
我把轴心部分留给你。我假设你想要的是
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
;
这将为您提供未插入的数据。如果要使用它构建数据透视表,我建议您查看、和/或。简而言之,您必须构建一条“动态”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;
我把pivot部分留给您。因此,我能够使用我创建的一个过程来确定一个适合我需要的解决方案,该过程将您推荐的解决方案以及我在本网站上找到的其他一些解决方案的概念组合在一起。该程序的总和以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)
因此,我能够使用我创建的一个过程来确定一个适合我需要的解决方案,该过程将您推荐的解决方案以及我在本网站上找到的其他一些解决方案的概念整合在一起。该程序的总和以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)
因此,我能够使用我创建的一个过程来确定一个适合我需要的解决方案,该过程将您推荐的解决方案以及我在本网站上找到的其他一些解决方案的概念整合在一起。该程序的总和以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)
因此,我能够使用我创建的一个过程来确定一个适合我需要的解决方案,该过程将来自您推荐的解决方案以及我在本文中找到的其他一些解决方案的概念放在一起