【问题标题】:SQL Join :: Fetching records outside join conditionSQL Join :: 获取连接条件外的记录
【发布时间】:2019-01-15 16:19:44
【问题描述】:

我有 2 张桌子 A 和 B
A

B

要求是使用 id 列连接两个表,此外,如果获取的名称值具有另一个具有不同 id 的记录,则还应获取该记录。就像下面的截图一样。
输出:

要求

  • 表 B 的大小为 TB。两个表的单连接将是 最好的
  • 查询需要在 hive 上执行

【问题讨论】:

  • 同名记录可以多于2条吗?
  • 它可以有更多的记录。桌子很大。

标签: join hive hiveql


【解决方案1】:

我不熟悉 HiveQL,但对于常规 SQL,您需要将表 B 第二次连接到自身作为查询的一部分。

select
    b_name.id, b_name.name
from
    #table_A a                  
    join #table_B b             -- This table gets the "name" value for lookup
        on (a.id=b.id)
    join #table_B b_name        -- This is the table you want to pull your "output" from
        on (b.name=b_name.name)

这个查询本质上是说你需要在表B中找到“name”列的值,在表A中有一个匹配的ID,然后在表B中查找所有具有该name值的行。

【讨论】:

  • 感谢您的意见。但在现实世界的场景中,表 B 的大小为 TB。所以第二次加入将是昂贵的。这就是我发布示例数据而不是实际表格的原因。
  • 你试过了吗?如果 A 很小,名称不会出现那么多次,有适当的索引(如果适用于 Hive),那么成本应该不会那么高。无论如何,你必须找到所有的名字,所以没有其他方法。也许它支持一些 `where exists (subselect) 语法,但实际上工作量相同。
  • 在这种情况下,查询会扫描整个表两次吗?假设没有索引。
  • 显然是indexes are removed in Hive 3.0,但是具有自动重写功能的物化视图可能会产生类似的结果。
  • Oracle 中的先验连接是一项非常昂贵的操作。您在查询中提到某个表一次这一事实并不能保证它会更快。
【解决方案2】:

您可以多次加入同一张表。因此,在下面的查询中,b1 将为您提供 A 中 id 的所有名称,b2 按名称连接,以获取不在 A 中的所有额外 id。

select
  b2.*
from
  A 
  inner join B b1 on b1.id = A.id
  inner join B b2 on b2.name = b1.name

【讨论】:

    猜你喜欢
    • 2016-02-11
    • 1970-01-01
    • 2018-09-22
    • 2021-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-14
    相关资源
    最近更新 更多