【问题标题】:BigQuery left join seems to be doing a cross join insteadBigQuery 左连接似乎正在执行交叉连接
【发布时间】:2018-09-16 11:58:46
【问题描述】:

我在 BigQuery 中有两个表 - 一个包含 ppc 广告数据,另一个包含查询。我想加入两者,这样我就可以报告 ppc 收入与每天的支出。

这最初感觉很简单,但我已经尝试了简单的左连接和子查询,并且在两者都遇到了一些障碍后,我专注于左连接。

我有:

#standardSQL
SELECT 
  CAST(ppc.Date AS DATE) AS Date,
  COUNT(1) AS `Rows`,
  COUNT(DISTINCT(ppc.ID)) AS `PPCRows`,
  COUNT(DISTINCT(EnquiryId)) AS `EnquiryRows`
FROM
  `db.ppc_data.adgroup_performance_summary_report` ppc
LEFT JOIN
  `db.enquiries.output_final_scheduled` led
ON CAST(ppc.Date AS DATE) = CAST(led.EnquiryDateTime AS DATE)
WHERE
  SUBSTR(CAST(led.EnquiryDateTime AS STRING), 1, 7) = "2018-01"
GROUP BY 1

尽管被定义为左连接,但返回的数据表明(我认为)这是在进行交叉连接 - Rows 列的值是 PPC RowsEnquiry Rows 的乘积:

我真的不想将COUNT(DISTINCT(whatever)) 考虑到我接下来需要添加的所有聚合列中!

另外,它需要很长时间才能运行 - 有没有更有效的方法来编写此查询?

【问题讨论】:

  • 您的查询实际上是在执行inner join,但这不是您的问题。您显然缺少某种join 条件,但没有示例数据或表格布局,很难判断问题所在。
  • 只是检查 - 上面的结果对应于 LEFT JOIN 或 INNER JOIN 的语句?很困惑,因为我看到了 LEFT JOIN 但@GordonLinoff 提到了 INNER JOIN
  • use text, not images/links, for text (including code, tables & ERDs)。使用图片只是为了方便补充文本和/或无法在文本中给出的内容。
  • 嗨。找出返回的左连接:行上的内连接加上由空值扩展的不匹配的左表行。由于您的 where 仅适用于非空右表列,因此它会删除任何空扩展行,因此它是“将左连接变为内连接”。此外,您正在聚合连接,但您可能希望连接两个连接聚合。找出什么是交叉连接——它是真正的内连接。请阅读minimal reproducible example 并采取行动。检查小的输入和中间计算,看看发生了什么。您甚至没有说每个输入想要什么输出,我们如何提出解决方案?
  • 谢谢你@philipxy - 明白了 - where clause effectively transformed left to inner - 我不确定 - 我认为 OP 可能会在 Gordon 发表评论后立即纠正他的问题,因为它看起来在几分钟内完成

标签: sql join google-bigquery left-join cross-join


【解决方案1】:

这绝对不是CROSS JOIN
这将是 - 如果COUNT(1)COUNT(ppc.ID)COUNT(EnquiryId) 的产物。

同时,如果您没有得到预期的结果 - 请发布描述您的用例的具体问题

【讨论】:

    【解决方案2】:

    您可能想在加入之前进行汇总:

    SELECT ppd.dte AS Date, ppc.rows as PPCRows,
           led.cnt as `EnquiryRows`
    FROM (SELECT CAST(ppc.Date AS DATE) as dte, COUNT(*) as rows
          FROM `db.ppc_data.adgroup_performance_summary_report`
          GROUP BY CAST(ppc.Date AS DATE)
         ) ppc LEFT JOIN
         (SELECT CAST(led.EnquiryDateTime AS DATE) as dte, COUNT(*) as rows
          FROM `db.enquiries.output_final_scheduled` led
          GROUP BY CAST(led.EnquiryDateTime AS DATE)
         ) led
         ON ppc.dte = led.dte
    WHERE led.EnquiryDateTime >= '2018-01-01' AND
          led.EnquiryDateTime < '2018-02-01'
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-14
      • 2021-01-01
      • 2017-11-06
      • 2022-08-18
      • 1970-01-01
      • 2017-11-03
      • 2013-02-25
      • 1970-01-01
      相关资源
      最近更新 更多