在mySQL中执行任意数量的自联接

时间:2013-09-25 17:46:45

标签: mysql sql join pivot-table self-join

我在mysql中有一个数据集,其中包含多个命名接口的带宽测试结果,包括测试执行的日期和接口的名称。示例数据集看起来像这样:

|  date  |  testResult  |  interface  |
---------------------------------------
| 12/25  |     32       |    eth0     |
| 12/25  |     21       |    eth0     |
| 12/25  |     25       |    eth0     |
| 12/26  |     30       |    eth0     |
| 12/27  |     33       |    eth0     |
| 12/25  |     12       |    eth1     |
| 12/25  |     16       |    eth1     |
| 12/27  |     3        |    vz0      |
| 12/26  |     120      |    virt1    |

我需要绘制给定日期每个界面的平均结果,所以我当前的解决方案是

SELECT `date`, AVG(`testResult`) as avg, `interface` FROM `tests` WHERE 1=1 
GROUP BY date, interface ORDER BY interface, date

这给我一个像

的结果
|  date  |     avg      |  interface  |
---------------------------------------
| 12/25  |     26       |    eth0     |
| 12/26  |     30       |    eth0     |
| 12/27  |     33       |    eth0     |
| 12/25  |     14       |    eth1     |
| 12/26  |     120      |    virt1    |
| 12/27  |     3        |    vz0      |

我的问题是我需要在日期“加入”(我认为)这个数据,并在当天为每个界面的平均值添加一列。结果集中的接口名称和数量不是常量,不能进行硬编码。我理想的结果集如下所示:

|  date  |  avg_eth0    |  avg_eth1   |  avg_virt1   |  avg_vz0   |
-------------------------------------------------------------------
| 12/25  |     26       |      14     |    NULL      |    NULL    |
| 12/26  |     30       |      NULL   |    120       |    NULL    |
| 12/27  |     33       |      NULL   |    NULL      |    3       |

有没有办法执行此连接,基本上是为interface列的每个唯一值创建一列?

2 个答案:

答案 0 :(得分:0)

我建议使用透视:

select date,
AVG(case when interface='eth0' then avg else 0)) as eth0,
AVG(case when interface='eth0' then avg else 0)) as eth1,
AVG(case when interface='virt1' then avg else 0)) as virt1,
AVG(case when interface='vz0' then avg else 0)) as vz0
from (
SELECT `date`, AVG(`testResult`) as avg, `interface` FROM `tests` WHERE 1=1 
GROUP BY date, interface ORDER BY interface, date) as z group by date

答案 1 :(得分:0)

如果不知道数据透视中列的不同值,则无法在任何SQL风格中生成数据透视表查询。

换句话说,您必须对每个接口硬编码一列,如@David Jashi的答案所示。

但这意味着在编写SQL查询之前,首先需要先了解接口的不同值。你可以通过第一步运行查询来完成它:

SELECT DISTINCT interface FROM `tests`;

然后遍历结果,将更多列附加到SQL查询以执行数据透视。

很抱歉,SQL无法查询接口,同样的查询也会在遇到数据中的不同值时动态添加更多列。您需要运行两个查询。