MySQL记录集中的MySQL总和

时间:2016-09-30 18:21:52

标签: mysql

我有一个有趣的情况。我将发布SQL然后解释。

SELECT 
    `c`.`clusterName` AS `clusterName`,
    DATE_FORMAT(`p`.`insertedTS`, '%Y-%m-%d') AS `insertedDate`,
    MAX(`p`.`maxMemory`) AS `peakMaxMemory`,
    MIN(`p`.`maxMemory`) AS `minMaxMemory`,
    MAX(`p`.`usedMem`) AS `peakUsedMem`,
    MIN(`p`.`usedMem`) AS `minUsedMem`,
    MAX(`p`.`availMem`) AS `peakAvailMem`,
    MIN(`p`.`availMem`) AS `minAvailMem`,
    MAX(`p`.`numPoweredOnVms`) AS `peakPoweredOnVms`,
    MIN(`p`.`numPoweredOnVms`) AS `minPoweredOnVms`,
    (MAX(`p`.`maxMemory`) - MIN(`p`.`maxMemory`)) AS `deltaMaxMemory`,
    (MAX(`p`.`usedMem`) - MIN(`p`.`usedMem`)) AS `deltaUsedMem`,
    (MAX(`p`.`availMem`) - MIN(`p`.`availMem`)) AS `deltaAvailMem`,
    (MAX(`p`.`numPoweredOnVms`) - MIN(`p`.`numPoweredOnVms`)) AS `deltaPoweredOnVms`
FROM
    (`vtrend`.`clusters` `c`
    JOIN `vtrend`.`capacityDataRawPOSH` `p` ON ((`c`.`clusterID` = `p`.`clusterID`)))
GROUP BY `c`.`clusterName` , DATE_FORMAT(`p`.`insertedTS`, '%Y-%m-%d')
ORDER BY `c`.`clusterName`

结果如下:

clusterName,insertedDate,peakMaxMemory,minMaxMemory,peakUsedMem,minUsedMem,peakAvailMem,minAvailMem,peakPoweredOnVms,minPoweredOnVms,deltaMaxMemory,deltaUsedMem,deltaAvailMem,deltaPoweredOnVms
Some-Cluster,2016-09-20,221,221,111,111,111,111,17,17,0,0,0,0
Some-Cluster,2016-09-21,221,221,111,111,111,111,17,17,0,0,0,0
Some-Cluster,2016-09-22,221,221,111,111,111,111,17,17,0,0,0,0
Some-Cluster,2016-09-23,221,221,111,111,111,111,17,17,0,0,0,0
Some-Cluster,2016-09-24,221,221,111,111,111,111,17,16,0,0,0,1
Some-Cluster,2016-09-25,221,221,111,111,111,111,17,17,0,0,0,0
Some-Cluster,2016-09-26,221,221,111,111,111,111,17,17,0,0,0,0
Some-Cluster,2016-09-27,221,221,111,111,111,111,17,17,0,0,0,0
Some-Cluster,2016-09-28,221,221,111,111,111,111,17,15,0,0,0,2
Some-Cluster,2016-09-29,221,221,111,111,111,111,17,17,0,0,0,0

所以我想要完成(并且失败)的是在末尾添加一个列,该列将显示numPoweredOnVms计数在一天中增加或减少。由于上面的每个记录代表整天的分组,每15分钟输入一次数据,我希望能够查看第一个记录和当天的numPoweredOnVms并从中减去当天的最后一个记录。并且要么获得正数(增加)或负数(减少)计数,我可以使用IF语句来表示“增加”或“减少”文本。

以下是原始数据的示例:

idcapacityDataRaw,insertedTS,clusterID,totalRamGb,maxMemory,availMem,usedMem,actualUsageRamGb,totalCpuMhz,maxMhz,usedMhz,numPoweredOnVms
739,"2016-09-20 16:50:12",29,384,221,111,111,111,268032,178688,3394,17
976,"2016-09-20 21:50:42",29,384,221,111,111,111,268032,178688,4072,17
1074,"2016-09-20 22:13:07",29,384,221,111,111,111,268032,178688,4683,17
1172,"2016-09-20 22:35:36",29,384,221,111,111,111,268032,178688,3916,17
1270,"2016-09-20 22:58:01",29,384,221,111,111,111,268032,178688,3857,17
1365,"2016-09-20 23:21:06",29,384,221,111,111,111,268032,178688,7867,17
1463,"2016-09-20 23:43:37",29,384,221,111,111,111,268032,178688,3971,17
1575,"2016-09-21 00:11:05",29,384,221,111,111,111,268032,178688,8196,17
2149,"2016-09-21 19:13:33",29,384,221,111,111,111,268032,178688,3758,17
2495,"2016-09-21 21:01:48",29,384,221,111,111,111,268032,178688,3927,16

所以基本上我希望能够从第一个记录和当天的最后一个记录中提取numPoweredOnVms并减去它们。现在有趣的部分是如何在多天内为多个集群执行此操作?我想我可能需要单独查看原始数据并按记录计算该记录,然后使用该视图作为此查询的支持,只是不确定。

1 个答案:

答案 0 :(得分:1)

将原始查询用作子查询,并让它返回每天的第一个和最后一个时间戳。然后与表联接以在每个时间获取该列的值。

SELECT c.clusterName, p.*,
       CASE SIGN(plast.numPoweredOnVms  > pfirst.numPoweredOnVms)
            WHEN -1 THEN 'Decrease'
            WHEN 0 THEN 'No change'
            ELSE 'Increase'
       END AS changePoweredOnVms
FROM vtrend.clusters AS c
JOIN (
    SELECT 
        clusterID,
        DATE(`insertedTS`) AS `insertedDate`,
        MAX(`maxMemory`) AS `peakMaxMemory`,
        MIN(`maxMemory`) AS `minMaxMemory`,
        MAX(`usedMem`) AS `peakUsedMem`,
        MIN(`usedMem`) AS `minUsedMem`,
        MAX(`availMem`) AS `peakAvailMem`,
        MIN(`availMem`) AS `minAvailMem`,
        MAX(`numPoweredOnVms`) AS `peakPoweredOnVms`,
        MIN(`numPoweredOnVms`) AS `minPoweredOnVms`,
        (MAX(`maxMemory`) - MIN(`maxMemory`)) AS `deltaMaxMemory`,
        (MAX(`usedMem`) - MIN(`usedMem`)) AS `deltaUsedMem`,
        (MAX(`availMem`) - MIN(`availMem`)) AS `deltaAvailMem`,
        (MAX(`numPoweredOnVms`) - MIN(`numPoweredOnVms`)) AS `deltaPoweredOnVms`
        MIN(insertedTS) AS firstTS,
        MAX(insertedTS) AS lastTS
    FROM `vtrend`.`capacityDataRawPOSH`
    GROUP BY clusterID, insertedDate) AS p ON p.clusterID = c.clusterID
JOIN vtrend.capacityDataRawPOSH AS pfirst ON pfirst.clusterID = p.clusterID AND pfirst.insertedTS = p.firstTS
JOIN vtrend.capacityDataRawPOSH AS plast ON plast.clusterID = p.clusterID AND plast.insertedTS = p.lastTS

此外,使用DATE(insertedTS)而不是DATE_FORMAT(insertedTS, '%Y-%m-%d')将时间戳转换为日期。 %Y-%m-%d是显示日期时使用的默认格式。