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

在mySQL中执行任意数量的自联接,mysql,sql,join,pivot-table,self-join,Mysql,Sql,Join,Pivot Table,Self Join,我在mysql中有一个数据集,其中包含多个命名接口的带宽测试结果,以及执行测试的日期和接口的名称。示例数据集如下所示: | date | testResult | interface | --------------------------------------- | 12/25 | 32 | eth0 | | 12/25 | 21 | eth0 | | 12/25 | 25 | e

我在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    |
|  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       |
我需要绘制给定日期每个接口的平均结果,因此我当前的解决方案是

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  |  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    |
|  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       |

是否有一种执行此联接的方法,基本上就是为接口列的每个唯一值创建一列?

我建议使用数据透视:

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

如果不知道pivot中的列的不同值,就不能以任何风格的SQL生成pivot表查询

换句话说,每个接口必须硬编码一列,如@davidjashi的答案所示

但这意味着您需要先知道接口的不同值,然后才能编写SQL查询。您只需运行一个查询作为第一步:

SELECT DISTINCT interface FROM `tests`;
然后在结果上循环,向SQL查询追加更多列以进行透视


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

在mysql中不可能实现交叉表,您需要应用程序级代码。看到了吗?您可以生成查询并执行它吗?有非常公式化的查询可以做到这一点,但您需要查询哪些值首先出现。。或者只使用excel中的数据透视表;