【问题标题】:google BigQuery giving random results when joining within WITH clause在 WITH 子句中加入时,谷歌 BigQuery 给出随机结果
【发布时间】:2021-11-06 19:33:09
【问题描述】:

我想对以下问题进行一些解释: 我正在使用 with 子句创建一个表。我创建了一个 pre_final 表,我可以在其中说来自客户的前 3 个订单。想象一个示例客户的三列和三行

.

现在我需要聚合这张表,让每个客户只有一行,以及他所有的前 3 种产品。想象一下结果表

.

我试图通过在条件 email = email 的条件下将第一个表相互连接 2 次来实现这一点,并始终声明第一个表的 rating = 1,第二个连接的 rating = 2,第三个连接的 rating = 3 .

    from table a
    left join table b on a.email = b.email AND b.rating= 2 
    left join prepExport2 c on a.email = c.email AND c.pom_cnt = 3
where a.rating = 1

我坚信这必须有效,但是,在 BigQuery 中,我总是得到随机结果。比如决赛桌是这样的:

.

这根本不可能。我确信这适用于例如 Oracle 数据库。我可以了解一下发生了什么吗?再注意一次,所有这些都在 WITH CLAUSE 之内。指定给定评级时,电子邮件中没有重复。 Echal 评级/电子邮件组合仅存在一次。非常感谢。

【问题讨论】:

  • 你不需要加入。聚合成一个有序数组,然后您可以为您的产品选择偏移量 0、1、2。它更简单,无需加入。
  • 很容易提出另一个更有效、更可靠的解决方案。但是,如果您想要解释为什么您当前的代码不能按预期工作 - 您真的应该展示代码的所有相关部分 - 而不仅仅是一小部分!因此,您需要澄清您希望我们为您提供什么帮助,如果只是解释,请提供更多代码!

标签: sql google-bigquery with-statement


【解决方案1】:

使用条件聚合:

select email,
       max(case when rating = 1 then product end) as product_1,
       max(case when rating = 2 then product end) as product_2,
       max(case when rating = 3 then product end) as product_3
from <whatever>
group by email;

我可以解释为什么您所看到的可能会发生,尤其是因为您没有显示导致问题的数据或生成中间结果的代码。

许多数据库不存储 CTE 的结果。相反,他们每次引用它时都会重新计算 CTE。你可能有这样的结构:

row_number() over (partition by email order by <something>) as rating

&lt;something&gt; 可能与给定的email 有联系。而且,不能保证结果集中的排序是什么。因此,两次运行相同的代码可以(并且确实)产生不同的结果。

上述解决方案解决了该问题,因为 CTE 仅评估一次。但是,您的代码可能存在不稳定问题,您可能希望通过添加一个附加的 order by 键来修复生成中间表的代码,这样就没有联系了。

【讨论】:

  • 非常感谢您的解释和提供的解决方案。你对part by 100% 正确。很抱歉没有提供更多代码,但它有数百行 + 由于代码中的敏感信息,我无法真正分享它。再次感谢!
  • @MartinPchal 。 . .如果这回答了您的问题,您可以接受答案。
猜你喜欢
  • 1970-01-01
  • 2020-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多