HIVE, как обновить существующие данные, если они существуют, на основании какого-либо условия и вставить новые данные, если не существует - PullRequest
0 голосов
/ 26 октября 2018

Я хочу обновить существующие данные, если они существуют, на основании какого-либо условия (данные с более высоким приоритетом должны быть обновлены) и вставить новые данные, если они не существуют.

Я уже написал запрос для этого, но каким-то образом он дублирует количество строк. Вот полное объяснение того, что я имею и чего хочу достичь:

Что у меня есть: Таблица 1 - столбцы - идентификатор, информация, приоритет

hive> select * from sample1;
OK
1   123     1.01
2   234     1.02
3   213     1.03
5   213423  1.32
Time taken: 1.217 seconds, Fetched: 4 row(s)

Таблица 2: столбцы - идентификатор, информация, приоритет

hive> select * from sample2;
OK
1   1234    1.05
2   23412   1.01
3   21      1.05
4   1232    1.1
2   3432423 1.6
3   34324   1.4

Я хочу, чтобы в итоговой таблице была только 1 строка на идентификатор с данными в соответствии с наибольшим приоритетом:

1   1234    1.05
2   3432423 1.6
3   34324   1.4
4   1232    1.1
5   213423  1.32

Я написал следующий запрос:

insert overwrite table sample1
select a.id,
case when cast(TRIM(a.prio) as double) > cast(TRIM(b.prio) as double) then a.info else b.info end as info,
case when cast(TRIM(a.prio) as double) > cast(TRIM(b.prio) as double) then a.prio else b.prio end as prio
from sample1 a
join 
sample2 b
on a.id=b.id where b.id in (select distinct(id) from sample1)
union all
select * from sample2 where id not in (select distinct(id) from sample1)
union all
select * from sample1 where id not in (select distinct(id) from sample2);

После выполнения этого запроса я получаю следующий результат:

hive> select * from sample1;
OK
1   1234    1.05
2   234     1.02
3   21      1.05
2   3432423 1.6
3   34324   1.4
5   213423  1.32
4   1232    1.1

Как изменить текущий запрос для достижения правильного результата. Есть ли другой метод / процесс, которым я могу следовать, чтобы достичь конечного результата. Я использую hadoop 2.5.2 вместе с HIVE 1.2.1. Я работаю на кластере из 6 узлов с 5 подчиненными и 1 NN.

Ответы [ 3 ]

0 голосов
/ 12 ноября 2018

Поскольку у меня было несколько строк идентификаторов для каждого идентификатора, я сначала консолидировал идентификаторы с помощью сценария спарк.Решение может быть найдено здесь: SPARK 2.2.2 - Объединение нескольких RDD, выдающих из памяти кроме, кроме.Результирующий RDD имеет 124 столбца.Каким должен быть оптимальный метод соединения? Затем я использовал запрос, упомянутый в вопросе, чтобы получить желаемый результат.

0 голосов
/ 07 декабря 2018

добавление к ранее хорошим ответам!попробуйте это также:

insert overwrite table UDB.SAMPLE1
select 
 COALESCE(id2,id )
,COALESCE(info2,info)
,COALESCE(priority2, priority)
from 
UDB.SAMPLE1 TAB1
full outer JOIN
(
select id2, info2, priority2
from
(
select 
 id       as id2
,info     as info2
,priority as priority2
,row_number() over (partition by id order by priority desc) rn
from UDB.SAMPLE2
)TAB2_wt
where TAB2_wt.rn =1
)TAB2
on TAB2.id2 = TAB1.id
;

select * from SAMPLE1;

+-----+----------+-----------+--+
| id  |   info   | priority  |
+-----+----------+-----------+--+
| 1   | 1234     | 1.05      |
| 2   | 3432423  | 1.6       |
| 3   | 34324    | 1.4       |
| 4   | 1232     | 1.1       |
| 5   | 213423   | 1.32      |
+-----+----------+-----------+--+
0 голосов
/ 26 октября 2018

Используйте FULL JOIN, он вернет все соединенные строки плюс все несоединенные строки слева и все несоединенные строки из правых таблиц.Таблица sample2 содержит дублированные строки на id, поэтому объединение дублирующих строк использует аналитическую функцию row_number() для выбора только строк с наивысшим приоритетом из sample2 таблицы:

insert overwrite table sample1
select 
      nvl(a.id, b.id) as id,
      case when cast(TRIM(a.prio) as double) > cast(TRIM(b.prio) as double) then a.info else b.info end as info,
      case when cast(TRIM(a.prio) as double) > cast(TRIM(b.prio) as double) then a.prio else b.prio end as prio
from ( select a.*, row_number() over (partition by id order by prio desc) rn 
         from sample1 a
     ) a
     full join 
          ( select b.*, row_number() over (partition by id order by prio desc) rn
              from sample2 b
          ) b on a.id=b.id and b.rn=1 --join only with highest priority rows
where a.rn=1;

Если sample1 таблица также содержит несколько строк на id (это не в вашем примере), примените ту же технику, используя row_number к таблице sample1.

См. Также ответ о слиянии, используя full join: https://stackoverflow.com/a/37744071/2700344

Также с Hive 2.2 вы можете использовать ACID Merge, см. примеры

...