比较 2 个配置单元表以查找没有任何唯一列/时间戳的更新/插入/删除记录并将其附加到 Hadoop 中的基表
Posted
技术标签:
【中文标题】比较 2 个配置单元表以查找没有任何唯一列/时间戳的更新/插入/删除记录并将其附加到 Hadoop 中的基表【英文标题】:Comparing 2 hive tables for finding updated/inserted/deleted records without any unique column/timestamp and appending it to base table in Hadoop 【发布时间】:2017-05-05 10:23:23 【问题描述】:Base_table(从源加载第 1 天)
**Id Name City Country**
7682 Stuart Frankfurt Germany
8723 Micke Paris France
2355 Niki New york USA
2097 Deny Italy Rome
new_table(从源加载第 02 天)
**Id Name City Country**
7682 Stuart *Darmstadt* Germany
8723 Micke Paris France
2355 Niki New york USA
*9057 Bony Prague Prague*
比较上述 2 个表格时,可以看到以下 3 个变化。
记录 ID 7682 的城市名称在第 2 天加载时更改为达姆施塔特 记录 ID 2097 在第 02 天加载时被删除,它在第 01 天加载时存在 在第 02 天加载时插入了 ID 为 9057 的新记录
以上3个变化都需要被捕获并附加到Base_table中
应从比较中捕获以下 3 条记录
7682 Stuart Darmstadt Germany
2097 Deny Italy Rome
9057 Bony Prague Prague
追加第 02 天更改后的 Base_table 输出
**Id Name City Country**
7682 Stuart Frankfurt Germany
8723 Micke Paris France
2355 Niki New york USA
2097 Deny Italy Rome
*7682 Stuart Darmstadt Germany*
*2097 Deny Italy Rome*
*9057 Bony Prague Prague*
我能够使用 SQL 连接获取插入和删除的记录,但无法获取更新的记录。为了获取更新的记录,我使用本地将文件复制到 linux 并进行比较,但它不适合大量数据。任何人都可以分享您处理此类场景的经验吗?
【问题讨论】:
请求的输出没有任何意义 感谢您的评论。添加了比较后所需的确切输出(3 条记录)。 正如您在我的两个答案中看到的那样,这已经很清楚了。目前尚不清楚在没有任何操作指示(插入/删除/更新)的情况下获取差异的意义何在,此外,将差异附加到基表的意义何在。 在base_table中追加记录是为了维护每条记录的历史值,即记录的版本控制。 所以您确定一条记录已从基表中删除,然后您将其插入基表中而没有任何迹象表明这是一条实际删除的记录? 【参考方案1】:select inline
(
array
(
case
when n.id is null then struct(b.*)
else struct (n.*)
end
)
)
from base_table as b
full join new_table as n
on n.id = b.id
where b.id is null
or n.id is null
or struct(b.*) not in (struct(n.*))
+------+--------+-----------+---------+
| col1 | col2 | col3 | col4 |
+------+--------+-----------+---------+
| 2097 | Deny | Italy | Rome |
| 7682 | Stuart | Darmstadt | Germany |
| 9057 | Bony | Prague | Prague |
+------+--------+-----------+---------+
【讨论】:
感谢您的回复。您能否在上述查询中添加有关如何处理更新记录的说明。struct(*)
是一个由记录的所有字段组合而成的结构。 struct(b.*) not in (struct(n.*))
是针对不受支持的 struct(b.*) != struct(n.*)
的解决方法。如果 2 条记录具有相同的 id
但 struct(b.*) != struct(n.*)
则记录之间存在差异,因此需要更新。
是否可以添加一个标志来指示记录是否已删除或插入或更新以及正确的列名?【参考方案2】:
select inline(array(rec))
from (select max(struct(tab,rec)).col2 as rec
from ( select 1 as tab,id,struct(*) as rec from base_table
union all select 2 as tab,id,struct(*) as rec from new_table
) t
group by id
having count(*) = 1
or min(rec) not in (max(rec))
) t
+------+--------+-----------+---------+
| col1 | col2 | col3 | col4 |
+------+--------+-----------+---------+
| 2097 | Deny | Italy | Rome |
| 7682 | Stuart | Darmstadt | Germany |
| 9057 | Bony | Prague | Prague |
+------+--------+-----------+---------+
【讨论】:
感谢您的回复。您能否在上述查询中添加有关如何处理更新记录的说明。struct(*)
是一个由记录的所有字段组合而成的结构。 min(rec) not in (max(rec))
是针对不受支持的 min(rec) != max(rec)
的解决方法。如果一组记录具有相同的id
但min(rec) != max(rec)
比集合中至少有不同的记录,则更新。以上是关于比较 2 个配置单元表以查找没有任何唯一列/时间戳的更新/插入/删除记录并将其附加到 Hadoop 中的基表的主要内容,如果未能解决你的问题,请参考以下文章
使用 SQL,我可以遍历复合键上的表以查找特定数据并计算新值吗?
在使用 oracle apex 加载数据时,我应该查找其他表以匹配 id 并提取列值