BigQuery 中的多个左连接

Posted

技术标签:

【中文标题】BigQuery 中的多个左连接【英文标题】:Multiple Left Joins in BigQuery 【发布时间】:2018-06-28 22:58:07 【问题描述】:

我正在尝试使我在 BigQuery 中的当前正在运行的 SQL 查询更加精简,但遇到了以下问题:


错误:ON 子句必须是 AND of = 比较每个表中的一个字段名称,所有字段名称都以表名称为前缀。考虑使用标准 SQL .google.com/bigquery/docs/reference/standard-sql/),它允许不等式 JOIN 以及涉及表达式和残差谓词的比较。


下面是给出上述错误的查询。第一个 LEFT JOIN 有效。当我在下面添加第二个时,我开始收到错误。我要做的是获取人类可读的 own.o.firstname 和 own.o.lastname 值,而不是交易记录的 owner_id 值(o.properties.hubspot_owner_id.value),但为了做到这一点,我需要加入一些表。

我不得不在第二个 JOIN 的 ON 子句上使用 CAST,因为每个表的各自架构中的字段类型不同。如果我不这样做,我会收到以下错误:错误:连接键 o.properties.hubspot_owner_id.value (string) 和 o.ownerid (int64) 的类型无法自动强制。

WHERE 子句只是一个禁止列表,不返回已从数据库中删除的条目。

SELECT o.*
FROM (
  SELECT
    o.dealid,
    o.properties.dealname.value,
    stages.Label,
    o.properties.closedate.value,
    o.properties.hubspot_owner_id.value,
    own.o.firstname,
    own.o.lastname,
    o.properties.amount.value,
    o.properties.createdate.value,
    o.properties.pipeline.value,
    o.associations.associatedcompanyids,
    ROW_NUMBER() OVER (PARTITION BY o.dealid ORDER BY o._sdc_batched_at DESC) as seqnum
  FROM [sample-table:hubspot.deals] o
  LEFT JOIN [sample-table:hubspot.sales_stages_lookup] stages ON o.properties.dealstage.value = stages.Internal_Value
  LEFT JOIN [sample-table:hubspot.owners_reporting] own ON CAST(o.properties.hubspot_owner_id.value AS INTEGER) = CAST(own.o.ownerid AS INTEGER)) o
WHERE o.dealid NOT IN (SELECT objectid FROM [sample-table:hubspot_suppression_list.data] WHERE subscriptiontype = 'deal.deletion') AND seqnum = 1

【问题讨论】:

【参考方案1】:

在 BigQuery 中改用 standard SQL,它支持将表达式作为 ON 子句的一部分:

#standardSQL
SELECT o.*
FROM (
  SELECT
    o.dealid,
    o.properties.dealname.value AS dealname_value,
    stages.Label,
    o.properties.closedate.value AS closedate_value,
    o.properties.hubspot_owner_id.value AS hubspot_owner_id_value,
    own.o.firstname,
    own.o.lastname,
    o.properties.amount.value AS amount_value,
    o.properties.createdate.value AS createdate_value,
    o.properties.pipeline.value AS pipeline_value,
    o.associations.associatedcompanyids,
    ROW_NUMBER() OVER (PARTITION BY o.dealid ORDER BY o._sdc_batched_at DESC) as seqnum
  FROM `sample-table.hubspot.deals` o
  LEFT JOIN `sample-table.hubspot.sales_stages_lookup` stages ON o.properties.dealstage.value = stages.Internal_Value
  LEFT JOIN `sample-table.hubspot.owners_reporting` own ON CAST(o.properties.hubspot_owner_id.value AS INT64) = CAST(own.o.ownerid AS INT64)) o
WHERE o.dealid NOT IN (SELECT objectid FROM `sample-table.hubspot_suppression_list.data` WHERE subscriptiontype = 'deal.deletion') AND seqnum = 1

如需详细了解 BigQuery 中旧版 SQL 和标准 SQL 之间的区别,请参阅migration guide。

【讨论】:

感谢您的回答。表达式是查询中的问题所在吗? 是的。建议使用标准 SQL,因为它没有此限制或其他限制。 我刚刚使用标准 SQL 运行查询并收到以下错误...Duplicate column names in the result are not supported. Found duplicate(s): value。我已经尝试对查询进行大量修改,但仍然无法弄清楚。 看看这个编辑是否有帮助。问题是查询在名为value 的结果中生成了多个列,但您可以为它们指定不同的名称来解决错误。 做到了!我还意识到内部查询返回了很多名为value 的列,并最终通过AS 为每个列使用了别名。它修复了它并最终使列名更有意义。感谢您的所有帮助 - 衷心感谢!

以上是关于BigQuery 中的多个左连接的主要内容,如果未能解决你的问题,请参考以下文章

在 BIGQUERY 上使用 UNNEST 左连接

字符串列表上的 BigQuery 左连接返回 null

MSSQL:左连接三个表中的多个列

如何优化 MySQL 中的多个左连接?

在pyspark中加入2个表,多个条件,左连接?

在 Google BigQuery 中的最近一个或多个日期上左加入