【问题标题】:SQL simplified group by and average (flatten rows aggregation based on multiple columns)SQL 简化分组和平均(基于多列扁平行聚合)
【发布时间】:2018-01-09 21:48:02
【问题描述】:

我有三个表都通过“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 都是相同的。 但是,我希望在平均 T3_data 之前的列中没有那么多 group by 语句。有没有办法让group byiddistinct_value 产生相同的输出?

【问题讨论】:

  • 嗯,这对我来说看起来不错

标签: mysql aggregate aggregate-functions


【解决方案1】:

是的,有可能。

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

SQL99 及更高版本根据可选功能 T301 允许此类非聚合,如果它们在功能上依赖于 GROUP BY 列:如果 name 和 custid 之间存在这种关系,则查询是合法的。例如,如果客户的主键被托管,就会出现这种情况。

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

如果你有更早的mysql版本,那么你仍然可以使用mysql的特殊聚合功能any_value()

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

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

【讨论】:

  • 这是一个非常有帮助的答案。我查看了 any_value() 文档。我不确定它是否会有所帮助。如果 group by 语句中不包含非聚合列(例如 Color),则错误为:Invalid operation: column "t1.color" must appear in the GROUP BY clause or be used in an aggregate function; 1 statement failed.
  • 我真的没有什么要补充的。这些是您拥有的 3 个选项,根据您的 mysql 版本和适合您的目的使用您可以使用的一个。 any_value() 上的文档有示例代码供您使用和详细解释。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-05-17
  • 2019-08-22
  • 1970-01-01
  • 2018-11-07
  • 1970-01-01
  • 1970-01-01
  • 2016-03-28
相关资源
最近更新 更多