如何仅从多个 ORC 文件(通过 Hive table)检索最新版本的记录,每个记录包含多个版本?

How to retrieve only the latest version of the records from multiple ORC files (via a Hive table) which contain multiple versions for each record?

我有下面提到的一个 table 的 orc 文件,叫做 EXAM_RESULTS. 这个 table 首先有一个初始加载,然后会有增量加载。通过增量加载获得的新记录可能会将新记录带入 EXAM_RESULTS table 或现有记录的更新版本。

前四个 ORC 文件以 part-m-0000000003 结尾的文件来自初始加载,其他来自在不同日期和时间执行的不同增量加载是可以的在文件名中的日期时间信息中可以看到。

-rw-r--r--   3 mysql hdfs      15808 2019-08-19 11:55 /INFO/CLASSROOM/TEST_MARKS/EXAM_RESULTS/EXAM_RESULTS_2019-08-19_11-55-49.355.orc
-rw-r--r--   3 mysql hdfs      22068 2019-08-19 12:33 /INFO/CLASSROOM/TEST_MARKS/EXAM_RESULTS/EXAM_RESULTS_2019-08-19_12-33-37.642.orc
-rw-r--r--   3 mysql hdfs      15714 2019-08-19 12:42 /INFO/CLASSROOM/TEST_MARKS/EXAM_RESULTS/EXAM_RESULTS_2019-08-19_12-42-10.203.orc
-rw-r--r--   3 mysql hdfs      20297 2019-08-19 12:52 /INFO/CLASSROOM/TEST_MARKS/EXAM_RESULTS/EXAM_RESULTS_2019-08-19_12-52-08.658.orc
-rw-r--r--   3 mysql hdfs      17082 2019-08-19 18:11 /INFO/CLASSROOM/TEST_MARKS/EXAM_RESULTS/EXAM_RESULTS_2019-08-19_18-11-53.338.orc
-rw-r--r--   3 mysql hdfs      14446 2019-08-20 07:59 /INFO/CLASSROOM/TEST_MARKS/EXAM_RESULTS/EXAM_RESULTS_2019-08-20_07-59-31.911.orc
-rw-r--r--   3 mysql hdfs      27128 2019-08-20 12:55 /INFO/CLASSROOM/TEST_MARKS/EXAM_RESULTS/EXAM_RESULTS_2019-08-20_12-55-10.985.orc
-rw-r--r--   3 hdfs   hdfs   18652678 2019-07-30 14:37 /INFO/CLASSROOM/TEST_MARKS/EXAM_RESULTS/part-m-00000
-rw-r--r--   3 hdfs   hdfs   22259778 2019-07-30 14:37 /INFO/CLASSROOM/TEST_MARKS/EXAM_RESULTS/part-m-00001
-rw-r--r--   3 hdfs   hdfs   16816786 2019-07-30 14:37 /INFO/CLASSROOM/TEST_MARKS/EXAM_RESULTS/part-m-00002
-rw-r--r--   3 hdfs   hdfs   18608955 2019-07-30 14:37 /INFO/CLASSROOM/TEST_MARKS/EXAM_RESULTS/part-m-00003

现在,我想从 table 查询记录,这样我的 SELECT 查询输出每条记录的最新版本。

例如: 现有的 table 显示以下信息(也将是 SELECT * FROM TEST_MARKS.EXAM_RESULTS 查询的输出):

Student_Name    marks_sub1  marks_sub2  marks_sub3  marks_sub4  total_marks avg_marks
 ABC            67          89          76          93          325         81.25
 XYZ            23          14          80          56          173         43.25
 PQR            50          67          98          44          259         64.75
 ABC            67          92          78          93          329         82.25
 XYZ            88          61          76          56          281         70.25

这里,学生 ABCXYZ 的分数已更新,而 PQR 的数据没有变化 - ABC 和 [=21 的更新记录=] 通过增量加载被插入到 table 中。

我想要实现的是我想要一个 SELECT 查询应该只显示每条记录的最新记录。例如,我的查询结果应该显示以下数据:

Student_Name    marks_sub1  marks_sub2  marks_sub3  marks_sub4  total_marks avg_marks
 ABC            67          92          78          93          329         82.25
 XYZ            88          61          76          56          281         70.25
 PQR            50          67          98          44          259         64.75

我不知道该怎么做,因为我的 table 本身没有可用于过滤最新数据的列。我需要使用文件名中的日期和时间信息,以便在我的 SELECT 查询中执行此过滤。

我对 Hive 和 HDFS 完全陌生,不知道如何实现。

有人可以帮我吗?

您可以在 Hive 中使用 INPUT__FILE__NAME 虚拟列并记录最大文件名。

像这样的新文件:EXAM_RESULTS_2019-08-20_12-55-10.985.orc 包含可排序格式的日期,并且可以对整个文件名进行排序。 像这样的旧文件 part-m-00000 也可以排序,但问题是与新文件 'part-m-00000'<'EXAM_RESULTS_2019-08-20_12-55-10.985.orc' = false 比较时。我建议从文件名中删除 part-m- 以使其以正确的方式排序,因此 '00000'< 'EXAM_RESULTS_2019-08-20_12-55-10.985.orc'。然后可以使用 row_number 查找最新记录:

select Student_Name    marks_sub1  marks_sub2  marks_sub3  marks_sub4  total_marks avg_marks
from 
(
select e.*, row_number() over(partition by Student_Name order by filename desc) rn
from
(select regexp_replace(INPUT__FILE__NAME,'part-m-','') filename, e.* from TEST_MARKS.EXAM_RESULTS e )e
)s
where rn=1;