【问题标题】:Big Query SQL sum values based on conditions基于条件的 Big Query SQL 求和值
【发布时间】:2020-08-20 22:49:22
【问题描述】:

我有一个查询,我试图根据两列的组合来组合表和求和结果。我想将表 2 和表 3 中的组与表 1 的名称和计数相匹配。然后,应将计数相加,以便每个名称都列出一次。但是,如果工作的人是 UU 组和 Z 组,那么他/她应该需要将他们的组 Z 计数与他们的组 UU 计数分开列出。如果此人作为 Z 组和 UU 组工作,他们将被列出两次。我需要根据特定条件拆分结果(下例中 Portal 和 Group 的组合)

Table 1
+--------+------+-------+
| Portal | Name | Count |
+--------+------+-------+
| A      | Bob  |     3 |
| A      | Joe  |     6 |
| B      | Joe  |     6 |
| B      | Bob  |     2 |
| C      | Bob  |     5 |
+--------+------+-------+

Table 2
+-------+------+
| Group | Name |
+-------+------+
| Z     | Bob  |
| Y     | Joe  |
+-------+------+ 

Table 3
+-------+------+
| Group | Name |
+-------+------+
| UU    | Bob  |
| UU    | Jill |
+-------+------+

Output
+-------+------+-------+
| Group | Name | Count |
+-------+------+-------+
| Z     | Bob  |     8 |
| UU    | Bob  |     2 |
| Y     | Joe  |    12 |
+-------+------+-------+

请注意,Bob 的 Portal B 被单独计算,因为他在 UU 组中。 UU 组仅在门户 B 中工作。Bob 的门户 A 和 C 相加在一起,因为他是这些门户中的 Z 组。与此同时,Joe 将他的所有计数汇总在一行中,因为他根本不是 UU。提前感谢您提供任何见解。

【问题讨论】:

  • 组和门户之间的关系如何?您的样本数据没有任何迹象。另一方面,您必须列出用户组,其目的似乎不清楚。
  • 您应该更详细地解释 - 输出中的每一行。到目前为止 - 它非常不清楚和令人困惑,以至于完全没有意义
  • 请解释您如何计算82。你怎么知道“A”和“C”和“Z”一起去?
  • 唯一的关系是Group UU总是在Portal B中。除此之外,没有任何关系。任何组都可以在任何门户中工作。输出:Bob 在除门户 B 之外的每个门户中都是 Z。通过添加 5+3(来自门户 A 和 C 的计数),您得到 8。Bob 是门户 B 中的 UU,所以我们从门户 B 中得到 2。Joe 是组 Y,所以我们将他所有门户中的所有计数加起来,根本没有分开。一个人可以是 Z 组和 UU 组,但他们只能在 Portal B 中作为 UU 组工作。
  • 我正在做的是将组添加到名称中,并将所有门户的所有计数加在一起。唯一的例外是,当一个人是 Group UU 角色时(仅出现在 Portal B 中),该计数需要分开。

标签: sql join count google-bigquery


【解决方案1】:

以下是 BigQuery 标准 SQL

试试下面

#standardSQL
WITH table1 AS (
  SELECT 'A' portal, 'Bob' name, 3 cnt UNION ALL
  SELECT 'A', 'Joe', 6 UNION ALL
  SELECT 'B', 'Joe', 6 UNION ALL
  SELECT 'B', 'Bob', 2 UNION ALL
  SELECT 'C', 'Bob', 5 
), table2 AS (
  SELECT 'Z' grp, 'Bob' name UNION ALL
  SELECT 'Y', 'Joe' 
), table3 AS (
  SELECT 'UU' grp, 'Bob' name UNION ALL
  SELECT 'UU', 'Jill' 
), all_groups AS (
  SELECT * FROM table2 UNION ALL
  SELECT * FROM table3
)
SELECT grp, name, 
  SUM(
    CASE 
      WHEN grp = 'UU' THEN
        CASE WHEN portal = 'B' THEN cnt ELSE 0 END
      WHEN grp != 'UU' AND flag THEN
        CASE WHEN portal = 'B' THEN 0 ELSE cnt END
      ELSE cnt
    END
  ) cnt
FROM (
  SELECT a.grp, a.name, b.portal, b.cnt, 
    0 != COUNTIF(grp = 'UU') OVER(PARTITION BY a.name) flag
  FROM all_groups a
  JOIN table1 b
  ON a.name = b.name
)
GROUP BY grp, name   

有输出

Row grp name    cnt  
1   Z   Bob     8    
2   UU  Bob     2    
3   Y   Joe     12   

【讨论】:

  • 这成功了。它确实两次列出了像 Bob 这样的人,即使他们只在门户 B 工作(不一定是我想要的),但计数为 0,不应该影响加权平​​均值。我可以解决它。我给小费,感谢您抽出宝贵时间。
【解决方案2】:

我认为您正在尝试根据门户的值使用不同的映射表。如果是这样,你可以这样做:

select 
    case when portal = 'B' then t3.group else t2.group end as grp,
    t1.name,
    sum(count) cnt
from table1 t1
inner join table2 t2 on t2.name = t1.name
inner join table3 t2 on t2.name = t1.name
group by 1, 2

如果您可能在任何组表中缺少记录,请改用left join

【讨论】:

  • 不幸的是,这个方法没有分离,它按预期按组列出了UU组和B组的人,但没有分离出计数。我假设将表 3 别名标记为 t2 是一个错误。您的输出是“Z Bob 10”,然后是“UU Bob 10”。您希望查看整个 84 行查询吗?它做我想做的一切,除了当我有一个人(鲍勃)与 UU 组和 Z 组时,鲍勃的两次被列为 UU 组,首先计数翻了一番,然后翻了两番。我担心如果我发布了整个代码,我会花一周的时间来解释它,如果有人花时间的话。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-18
  • 2022-07-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多