sql配置单元与子查询的聚合结果的比较

b4lqfgs4  于 2021-06-01  发布在  Hadoop
关注(0)|答案(1)|浏览(373)

我有一个这样的表(例如称为source):

-------------
|Name|ID|...|
-------------
|A   |1 |...|
|A   |2 |...|
|A   |3 |...|
|B   |1 |...|
|B   |2 |...|
|C   |1 |...|
-------------

因此,每个名称可能有多个条目,每个条目都有一个递增的id(按名称进行分区,您现在可能已经知道了)。
现在,我有另一个表(称为dest),我从源表中加载,例如daily batches。但是,我只想从源加载增量,因此如果我的dest表是这样的:

-------------
|Name|ID|...|
-------------
|A   |1 |...|
|A   |2 |...|
|B   |1 |...|
-------------

我只想将差异从源复制到目标,即:

-------------
|Name|ID|...|
-------------
|A   |3 |...|
|B   |2 |...|
|C   |1 |...|
-------------

由于其他原因,我不能使用时间戳或减号,因此找到差异的唯一方法是获取每个名称的max(id)并仅检索每个名称的条目>max(id)。
最快的实现是通过一个子查询来准备每个名称的所有max(id),并使用它来消除较小的id:

SELECT s.* FROM Source s 
LEFT JOIN (
 SELECT d.NAME, MAX(d.ID) AS MAX_ID
 FROM Dest d
 GROUP BY d.NAME) n
ON s.NAME = n.NAME
WHERE s.ID > COALESCE(n.MAX_ID,0)

但是,由于表中有很多条目,我认为这不会很好地执行,除非hive自动对其进行了足够的优化,我不确定这一点。
我希望做的事情是这样的:

SELECT s.* FROM Source s 
WHERE s.ID > (SELECT COALESCE(MAX(d.ID),0)
              FROM Dest d
              WHERE d.NAME = s.NAME)

这样我就避免了为所有条目计算max(id),而只为当前名称计算max(id)。但在 hive 里显然是不可能的。
所以我的问题是,在Hive中实现这种增量检测的最佳和最有效的方法是什么?

6mzjoqzu

6mzjoqzu1#

你为什么不直接用 left join 以及 where ?

SELECT s.*
FROM Source s LEFT JOIN
     Dest d
     ON s.NAME = d.NAME AND s.ID = d.ID
WHERE d.NAME IS NULL;

如果您真的需要使用 Dest ,然后你用 GROUP BY 在 hive 里应该很好。

相关问题