比较 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 条记录具有相同的 idstruct(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) 的解决方法。如果一组记录具有相同的idmin(rec) != max(rec) 比集合中至少有不同的记录,则更新。

以上是关于比较 2 个配置单元表以查找没有任何唯一列/时间戳的更新/插入/删除记录并将其附加到 Hadoop 中的基表的主要内容,如果未能解决你的问题,请参考以下文章

使用 SQL,我可以遍历复合键上的表以查找特定数据并计算新值吗?

在使用 oracle apex 加载数据时,我应该查找其他表以匹配 id 并提取列值

如果 A 列中的单元格为空白,则针对不同工作表中的数据集查找 B 列

Excel UDF 在已关闭的工作簿中引用表以进行查找

创建动态表以比较数据列

将所有列值与 Excel 中的单个单元格进行比较