SQL GROUP BY 其中任一列具有相同的值

SQL GROUP BY where either column has same value

我有以下table

User A | User B | Value
-------+--------+------
   1   |    2   |  60
   3   |    1   |  10
   4   |    5   |  50
   3   |    5   |  50  
   5   |    1   |  80
   2   |    3   |  10

我想将用户 a = x 或用户 b = x 的记录分组在一起,以便找到平均值。

例如用户 1 在 table 中出现了 3 次,一次是 'User A',两次是 'User B'。所以我想使用这三行来执行我的 AVG() 函数。

我需要最高和最低的平均值。这样的查询会将上面的 table 分解为以下几组:

User | Avg Value
-----+-----
  1  | 50
  2  | 35
  3  | 23.33
  4  | 50
  5  | 60

然后是return

Highest Avg | Lowest Avg
------------+-----------
     60     |   23.33

我知道 GROUP BY 将列具有相同值的记录收集在一起。我想收集两列中任一列具有相同值的记录。我搜索了很多解决方案,但似乎找不到满足我问题的解决方案。

便携式选项使用 union all:

select usr, avg(value) avg_value
from (
    select usera usr, value from mytable
    union all select userb, value from mytable
) t
group by usr

这为您提供了第一个结果集。然后,您可以添加另一层聚合以获得最大和最小平均值:

select min(avg_value) min_avg_value, max(avg_value) max_avg_value
from (
    select usr, avg(value) avg_value
    from (
        select usera usr, value from mytable
        union all select userb, value from mytable
    ) t
    group by usr
) t

在支持横向连接和 values() 的数据库中,最方便(也最有效)的表达方式如下:

select min(avg_value) min_avg_value, max(avg_value) max_avg_value
from (
    select usr, avg(value) avg_value
    from mytable t
    cross join lateral (values (usera, value), (userb, value)) as x(usr, value)
    group by usr
) t

例如,这将适用于 Postgres。在 SQL 服务器中,您只需将 cross join lateral 替换为 cross apply

您可以使用 union all 逆透视,然后聚合:

select user, avg(value)
from ((select usera as user, value) union all
      (select userb as user, value)
     ) u
group by user;

您可以通过另一个聚合级别获得极值:

select min(avg_value), max(avg_value)
from (select user, avg(value) as avg_value
      from ((select usera as user, value) union all
            (select userb as user, value)
           ) u
      group by user
     ) ua