2

所以我们正在我们部门做一些交通报告。因此,我们得到了一个名为 traffic_report 的表,它的构建类似于

╔════════════════╦═══════════╦═════════════════════╦═════════════╦═════════════╗
║    hostname    ║ interface ║      date_gmt       ║ intraf_mpbs ║ outraf_mbps ║
╠════════════════╬═══════════╬═════════════════════╬═════════════╬═════════════╣
║ my-machine.com ║ NIC-5     ║ 2013-09-18 09:55:00 ║          32 ║          22 ║
║ my-machine.com ║ NIC-5     ║ 2013-09-17 08:25:00 ║          55 ║          72 ║
║ my-machine.com ║ NIC-5     ║ 2013-09-16 05:12:00 ║          65 ║           2 ║
║ my-machine.com ║ NIC-5     ║ 2013-09-15 04:46:00 ║          43 ║           5 ║
║ my-machine.com ║ NIC-5     ║ 2013-09-14 12:02:00 ║          22 ║          21 ║
║ my-machine.com ║ NIC-5     ║ 2013-09-13 22:13:00 ║          66 ║          64 ║
╚════════════════╩═══════════╩═════════════════════╩═════════════╩═════════════╝

我想在发生的日期获取最大的流量输入和流量。我这样做的方法是这样的

SELECT hostname, interface, date_gmt, max(intraf_mbps) as max_in, max(outtraf_mbps) as max_out
FROM traffic_report
GROUP by hostname, interface

该方法产生这样的表

╔════════════════╦════════════╦═════════════════════╦════════╦═════════╗
║    hostname    ║ interface  ║      date_gmt       ║ max_in ║ max_out ║
╠════════════════╬════════════╬═════════════════════╬════════╬═════════╣
║ my-machine.com ║ NIC-5      ║ 2013-09-18 09:55:00 ║     66 ║      72 ║
╚════════════════╩════════════╩═════════════════════╩════════╩═════════╝

问题是,显示的 date_gmt 只是输入到表中的第一条记录的日期。

如何指示 SQL 向我显示 max(intraf_mbps) 发生的 date_gmt?

4

2 回答 2

4

您的问题与mysql 隐藏字段有关:

MySQL 扩展了 GROUP BY 的使用,以便选择列表可以引用未在 GROUP BY 子句中命名的非聚合列。这意味着前面的查询在 MySQL 中是合法的。您可以使用此功能通过避免不必要的列排序和分组来获得更好的性能。但是,这主要在每个未在 GROUP BY 中命名的非聚合列中的所有值对于每个组都相同时很有用。

Mysql 没有排名功能,也没有分析功能,为了得到你的结果,一种可读但性能很差的方法是:

SELECT hostname, 
       interface, 
       date_gmt, 
       intraf_mbps, 
       outtraf_mbps
FROM traffic_report T
where intraf_mbps + outtraf_mbps =
      ( select 
           max(intraf_mbps + outtraf_mbps) 
        FROM traffic_report T2
        WHERE T2.hostname = T.hostname and
              T2.interface = T.interface 
        GROUP by hostname, interface
      )

当然,您可以使用对索引更友好的方法或避免相关子查询来寻求解决方案。

请注意,我已经添加了进出两种费率。根据您的需求调整解决方案。

于 2013-09-18T08:42:42.413 回答
2

这些方法中的任何一种都应该有效:

第一个查询返回与最大输出值和输入值匹配的行,因此如果许多记录共享最大值或最小值,则可以返回多行。

SELECT * from traffic_report 
WHERE intraf_mpbs = (SELECT MAX(intraf_mpbs) FROM traffic_report) 
   or outraf_mpbs = (SELECT MAX(outraf_mpbs) FROM traffic_report)

第二个查询返回更多 MI 样式结果,如果需要,请添加其他字段。

SELECT "MAX IN TRAFFIC" AS stat_label,date_gmt AS stat_date, traffic_report.intraf_mpbs
  FROM traffic_report,(select MAX(intraf_mpbs) AS max_traf FROM traffic_report) as max_in
 WHERE traffic_report.intraf_mpbs = max_in.max_traf
 UNION
SELECT "MAX OUT TRAFFIC" AS stat_label,date_gmt AS stat_date, traffic_report.outraf_mpbs
  FROM traffic_report,(SELECT MAX(outraf_mpbs) AS max_traf FROM traffic_report) AS max_out
 WHERE traffic_report.outraf_mpbs = max_out.max_traf

希望这可以帮助。

于 2013-09-18T09:11:17.063 回答