如何在 BQ 中的数组字段上做相当于“不同”的操作?
Posted
技术标签:
【中文标题】如何在 BQ 中的数组字段上做相当于“不同”的操作?【英文标题】:How to do the equivalent of 'distinct' on array field in BQ? 【发布时间】:2021-06-14 01:53:32 【问题描述】:让我们获取以下数据:
也可以在BQ中用如下语句生成:
with x as (
select 1 as RowID, DATE('2014-01-01') as Date, [200, 300] as Payments, ["Contractor", "Monday"] as Tags union all
select 2 as RowID, DATE('2014-01-02') as Date, [100, 200, 200, 200, 700] as Payments, ["Contractor", "Bi-Weekly"] as Tags
)
select * from x
我将如何在以下右侧进行以下两个“不同”总计:
也就是说,我想得到一个不会重复计算的“总数”,或者更确切地说,只获取基于 RowID 的不同项目。
【问题讨论】:
【参考方案1】:如果我理解正确,那是您真正关心的总行数。您可以通过并行取消标签和付款来计算前两列。
然后对于总额,取消不带标签的付款:
with x as (
select 1 as RowID, DATE('2014-01-01') as Date, [200, 300] as Payments, ["Contractor", "Monday"] as Tags union all
select 2 as RowID, DATE('2014-01-02') as Date, [100, 200, 200, 200, 700] as Payments, ["Contractor", "Bi-Weekly"] as Tags
)
select tag, count(*), sum(payment)
from x cross join
unnest(x.payments) payment cross join
unnest(x.tags) tag
group by 1
union all
select 'Total', count(*), sum(payment)
from x cross join
unnest(x.payments) payment;
【讨论】:
漂亮,正是我想要的。以上是查询数组的常用方法吗?我总是争论正确的方法是“双重计算”还是进行总计以获得原始数据集的实际计数/总数。有没有更“正确”的方法来做到这一点? @David542。 . .这将获得您想要的计数。我认为没有比这更简单的方法了。 对,我的意思是这是用数组做双向相关事情的常用方法吗?还是经常重复计算? 我想一个更好的提问方式是,如果您要查看付款的“总计”,您希望看到$1900
或$3800
?还是更多地取决于具体情况,并且在不同的时间可能更可取?
I don't think there is a simpler method than this.
- 我认为我的回答提出了更简单的方法:o)【参考方案2】:
考虑下面
select tag, sum(payment) amount_paid, count(payment) payments_count
from data, unnest(tags || ['Total']) tag, unnest(payments) payment
group by tag
如果应用于您问题中的样本数据 - 输出是
【讨论】:
太棒了!添加order by (tag='total')
,以便阅读底部的总计。
您是否见过有人希望总数为3800
而不是您在与任何客户合作时所拥有的?或者如果有人曾经使用过数组,1900
是“正确”的答案吗?
根据我的经验 - 预计总数为 1900。从未见过预期 3800 的实际案例以上是关于如何在 BQ 中的数组字段上做相当于“不同”的操作?的主要内容,如果未能解决你的问题,请参考以下文章