SQL简化group by和average(基于多列展平行聚合)

时间:2018-01-09 21:48:02

标签: mysql aggregate aggregate-functions

我有三个表都是通过" id"柱。当所有三个人加入时,看起来有点像这样:

+----+-------+--------+-------------------+---------+
| id | Color | T1Data | distinct_value    | T3_data |
+----+-------+--------+-------------------+---------+
|  1 | green | ab     | A                 |      10 |
|  1 | green | ab     | A                 |      20 |
|  1 | green | ab     | B                 |     100 |
|  1 | green | ab     | B                 |     200 |
|  2 | blue  | xz     | A                 |      30 |
|  2 | blue  | xz     | A                 |      40 |
|  2 | blue  | xz     | B                 |     300 |
|  2 | blue  | xz     | B                 |     400 |
+----+-------+--------+-------------------+---------+

目前我只是SELECTING列,平均(AVG)T3数据,GROUP BY数据前面的每一列:

SELECT T1.id, T1.Color, T1Data, T2.distinct_value, avg(T3_data)
from T1 
left join T2 on T1.id = T2.id
left join T3 on (T3.id = T2.id and T3.distinct_value = T2.distinct_value)
group by T1.id, T1.Color, T1.Data, T2.distinct_value
order by T1.id;

结果如下:

+----+-------+--------+-------------------+---------+
| id | Color | T1Data | T2_distinct value | avg     |
+----+-------+--------+-------------------+---------+
|  1 | green | ab     | A                 |      15 |
|  1 | green | ab     | B                 |     150 |
|  2 | blue  | xz     | A                 |      35 |
|  2 | blue  | xz     | B                 |     350 |
+----+-------+--------+-------------------+---------+

这是期望的结果。我想知道是否有更有效的方法来调用聚合数据? ColorT1Data列是字符串,对于相同的ID,它们都是相同的。 但是,我希望没有尽可能多的group by语句,因为我在平均T3_data之前有列。有group by iddistinct_value会产生相同的输出吗?

1 个答案:

答案 0 :(得分:0)

是的,这是可能的。

如果你有MySQL 5.7.5或更新版本,那么你可以从列表中省略colort1data个字段,因为它们在功能上依赖于t1.id字段。请参阅handling group by上的mysql手册:

  

SQL99及更高版本允许每个可选功能T301使用这些非聚合,如果它们在功能上依赖于GROUP BY列:如果name和custid之间存在这种关系,则查询是合法的。例如,这就是客户的主要关键。

     

MySQL 5.7.5及更高版本实现了对功能依赖的检测。

如果你有一个早期的mysqlversìon,那么你仍然可以使用mysql的特殊聚合函数any_value()

  

当启用ONLY_FULL_GROUP_BY SQL模式时,此函数对于GROUP BY查询非常有用,因为MySQL拒绝您认为由于MySQL无法确定的原因而有效的查询。函数返回值和类型与其参数的返回值和类型相同,但不检查ONLY_FULL_GROUP_BY SQL模式的函数结果。

第三种解决方案显然是通过sql模式禁用唯一的完整组,但我不建议这样做。