2016-11-18 62 views
2

我的用例是使用存储在MySQL中的日志表创建stacked column graph如何高效查询堆积柱状图?

目前我有一个普通的柱形图,但我想通过site_id汇总数据,以便我可以看到柱的哪些部分归因于哪个场地。

我现有的柱状图的当前技术是获取日期列表,并根据日期对记录进行计数。然后我使用for循环创建我需要的14天期限,然后循环我的数据以将匹配的计数填入正确的日期。

SELECT DATE(`created`) AS `day`, 
     COUNT(`id`)  AS `count` 
FROM `api_logs` `ApiLogs` 
WHERE DATE(created) BETWEEN DATE_SUB(CURDATE(), INTERVAL 14 day) AND CURDATE() 
GROUP BY DATE(`created`) 
ORDER BY DATE(`created`) 

对于堆积图,虽然,我不能想办法整理在MySQL中的数据不进行大量查询或建立一个子查询核对每个站点计数。

是否有一个既定的模式来查询与堆叠柱形图容易兼容的结果?

如果有任何查询后处理解决方案,我的前端是使用PHP构建的。

+0

你在这里寻找一个数据透视表? – Shadow

回答

1

的问题是你需要一列每个站点

,如果你有网站的一组号码,然后就可以在SQL

SELECT DATE(`created`) AS `day`, 

     SUM(CASE WHEN `site_id` = 'A' THEN 1 ELSE 0 END) AS `site A`, 
     SUM(CASE WHEN `site_id` = 'B' THEN 1 ELSE 0 END) AS `site B` 

FROM `api_logs` `ApiLogs` 
WHERE DATE(created) BETWEEN DATE_SUB(CURDATE(), INTERVAL 14 day) AND CURDATE() 
GROUP BY DATE(`created`) 
ORDER BY DATE(`created`) 

否则手工打造的栏目,你可以建立列动态和聚集
使用谷歌的DataViewdata.group

首先,添加site_id到SQL

SELECT DATE(`created`) AS `day`, 
     `site_id`  AS `site_id`, 
     COUNT(`id`)  AS `count` 
FROM `api_logs` `ApiLogs` 
WHERE DATE(created) BETWEEN DATE_SUB(CURDATE(), INTERVAL 14 day) AND CURDATE() 
GROUP BY DATE(`created`), `site_id` 
ORDER BY DATE(`created`), `site_id` 

这将导致类似于以下...

['Date', 'Site', 'Count'], 
[new Date('11/17/2016'), 'A', 10], 
[new Date('11/17/2016'), 'B', 15], 
[new Date('11/17/2016'), 'C', 22], 

看到下面的工作片段的动态构建列...

google.charts.load('current', { 
 
    callback: function() { 
 
    // raw table data 
 
    var data = google.visualization.arrayToDataTable([ 
 
     ['Date', 'Site', 'Count'], 
 
     [new Date('11/17/2016'), 'A', 10], 
 
     [new Date('11/17/2016'), 'B', 15], 
 
     [new Date('11/17/2016'), 'C', 22], 
 
     [new Date('11/17/2016'), 'D', 8], 
 
     [new Date('11/16/2016'), 'A', 12], 
 
     [new Date('11/16/2016'), 'B', 6], 
 
     [new Date('11/16/2016'), 'C', 13], 
 
     [new Date('11/16/2016'), 'E', 14], 
 
     [new Date('11/15/2016'), 'A', 9], 
 
     [new Date('11/15/2016'), 'B', 16], 
 
     [new Date('11/15/2016'), 'D', 11] 
 
    ]); 
 

 
    // create view with columns for each site, then agg view 
 
    var view = new google.visualization.DataView(data); 
 
    var aggColumns = []; 
 
    var viewColumns = [0]; 
 

 
    data.getDistinctValues(1).forEach(function (site, index) { 
 
     viewColumns.push({ 
 
     calc: function (dt, row) { 
 
      if (dt.getValue(row, 1) === site) { 
 
      return dt.getValue(row, 2); 
 
      } 
 
      return null; 
 
     }, 
 
     label: site, 
 
     type: 'number' 
 
     }); 
 

 
     aggColumns.push({ 
 
     aggregation: google.visualization.data.sum, 
 
     column: index + 1, 
 
     label: site, 
 
     type: 'number' 
 
     }); 
 
    }); 
 

 
    view.setColumns(viewColumns); 
 
    var group = google.visualization.data.group(
 
     view, 
 
     [0], 
 
     aggColumns 
 
    ); 
 

 
    var chart = new google.visualization.ColumnChart(document.getElementById('chart_div')); 
 
    chart.draw(group, { 
 
     isStacked: true 
 
    }); 
 
    }, 
 
    packages: ['corechart'] 
 
});
<script src="https://www.gstatic.com/charts/loader.js"></script> 
 
<div id="chart_div"></div>