【问题标题】:What's the purpose of a JOIN where no column from 2nd table is being used?没有使用第二个表中的列的 JOIN 的目的是什么?
【发布时间】:2022-01-18 11:42:39
【问题描述】:

我正在查看我们在 hadoop 集群上作为分析的一部分运行的一些 hive 查询,但我无法理解其中的一个。这是 Hive QL 查询

SELECT 
    c_id, v_id, COUNT(DISTINCT(m_id)) AS participants, 
    cast(date_sub(current_date, ${window}) as string) as event_date 
from (
    select 
        a.c_id, a.v_id, a.user_id, 
        case 
            when c.id1 is not null and a.timestamp <= c.stitching_ts then c.id2 else a.m_id 
        end as m_id 
    from (
        select * from first
        where event_date <= cast(date_sub(current_date, ${window}) as string)
    ) a 
    join (
        select * from second
    ) b on a.c_id = b.c_id 
    left join third c 
    on a.user_id = c.id1
    ) dx 
group by c_id, v_id;

我已经更改了名称,但这是用于插入覆盖到另一个表的选择语句。 关于加盟

join (
        select * from second
    ) b on a.c_id = b.c_id 

除了连接条件之外,b 没有在任何地方使用,那么这个连接是否有任何用途?
是为了确保此联接仅具有第二个表中存在 c_id 的条目吗?如果这一切都在做,where IN 条件会更好。 或者我可以删除这个连接,它不会有任何区别。

谢谢。

【问题讨论】:

  • FROM 顶层的子查询需要有别名,不管你是否需要使用它,这就是语言的定义方式。这里的所有都是它的。 PS既然你需要ON的别名,你为什么还要问这个?你的问题到底是什么? PS 这可能是一个很容易找到的副本。但是你需要清楚、简洁、完整地向谷歌表达你的问题/目标/问题。
  • @philipxy 问题不是关于别名的需要,而是关于加入的需要
  • 那帖子就不清楚了。请阅读并编辑清楚(包括标题)。问 1 个(特定研究的非重复)问题。 (不是标题中的 1 和帖子中的 4。)无论如何,无论您要问什么,它都会很容易找到。
  • 我已经对帖子进行了一些编辑,但标题已经提到了加入的目的
  • 这没有任何改善。阅读帖子。问题是什么? PS“服务于任何目的”是什么意思?它在那里是因为作者想要根据语言定义的效果。您没有根据手册清楚地描述您看到的问题,并有明确的理由。 PSIs there any rule of thumb to construct SQL query from a human-readable description?

标签: sql hadoop join hive hql


【解决方案1】:
  1. 如果连接数据集中的连接键不唯一,则连接(任何内部、左侧或右侧)可以复制行。例如,如果a 包含带有c_id=1 的单行并且b 包含带有c_id=1 的两行,则结果将是带有a.c_id=1 的两行。
  2. 如果连接数据集中没有连接键,则连接(内部)可以过滤行。我相信这就是它的本意。

如果目标是只获取两个数据集中都存在键的行(过滤器)并且您不希望重复,并且您不使用连接数据集中的列,那么最好使用 LEFT SEMI JOIN 而不是 JOIN,它会起作用仅作为过滤器,即使连接数据集中有重复的键:

left semi join (
                select c_id from second
               ) b on a.c_id = b.c_id 

这是一种更安全的方法来过滤仅存在于 a 和 b 中的行并避免意外重复。

您可以将join替换为WHERE IN/EXISTS,但没有区别,它实现为相同的JOIN,检查EXPLAIN输出,您将看到相同的查询计划。更好地使用LEFT SEMI JOIN,它以高效的方式实现了不相关的IN/EXISTS。

如果您希望将其移动到 WHERE:

WHERE a.c_id IN (select c_id from second)

或相关的存在:

WHERE EXISTS (select 1 from second b where a.c_id=b.c_id)

但正如我所说,它们都是在内部使用 JOIN 运算符实现的。

【讨论】:

    猜你喜欢
    • 2021-08-05
    • 2020-08-13
    • 1970-01-01
    • 1970-01-01
    • 2012-10-10
    • 2013-02-28
    • 1970-01-01
    • 2021-06-01
    • 2022-01-16
    相关资源
    最近更新 更多