Hive SQL полное внешнее соединение с предложением Where - PullRequest
2 голосов
/ 25 февраля 2020

Я создаю полное внешнее объединение с предложением where. Однако он может генерировать только результат внутреннего соединения. Я подозреваю, что это связано с предложением where, но мне это нужно, когда условие добавляется. Итак, как мне создать запрос, удовлетворяющий обеим потребностям (как условию where, так и полному внешнему соединению)? Вот мой запрос.

select
  t1.key1 as key1_1
, t1.key2 as key2_1
, t1.key3 as key3_1
, t1.date as date_1
, t1.v1
, t2.key1 as key1_2
, t2.key2 as key2_2
, t2.key3 as key3_2
, t2.date as date_2
, t2.v2
from t1 
full outer join t2
on t1.key1 = t2.key1 and t1.key2 = t2.key2 and t1.key3 = t2.key3 
where datediff(t1.date, t2.date) between -5 and 5
; 

Пример данных

t1
key1 key2 key3 date        v1
A1   B1   C1   2015-01-01  10
A1   B2   C2   2015-01-01  11

t2
key1 key2 key3 date        v2
A1   B1   C1   2015-01-01  20
A1   B1   C1   2015-01-03  30
A1   B1   C1   2015-02-01  40
A1   B1   C1               50
A1   B1   C2   2015-01-02  60

Желаемый результат

key1_1 key2_1 key3_1 date_1     v1 key1_2 key2_2 key3_2 date_2     v2
A1     B1     C1     2015-01-01 10 A1     B1     C1     2015-01-01 20
A1     B1     C1     2015-01-01 10 A1     B1     C1     2015-01-03 30
                                   A1     B1     C1     2015-02-01 40
                                   A1     B1     C1                50
                                   A1     B1     C2     2015-01-02 60
A1     B2     C2     2015-01-01 11

Это все сценарии ios, которые я могу представить себе как сейчас же. Я могу добавить, если найду пропущенный сценарий ios. Моя точка зрения заключается в том, что должны быть включены следующие результаты:

  1. , если две таблицы удовлетворяют всем этим условиям, заданным с помощью ключей и даты, то они включаются, как показано в строках 1 и 2 в желаемом результате.
  2. если какое-либо из этих условий не будет выполнено, то мы сохраняем информацию одной таблицы в результате, как показано в строках 3, 4, 5 и 6, в желаемом результате.

РЕДАКТИРОВАТЬ: Основываясь на предложении @Gordon Linoff, я использовал объединение всех, чтобы решить эту проблему. Пожалуйста, посмотрите мое решение в моем ответе пост ниже.

Ответы [ 3 ]

1 голос
/ 25 февраля 2020

Возможно, вы просто захотите переместить логи c в предложение on:

from t1 full outer join
     t2
     on t1.key1 = t2.key1 and
        t1.key2 = t2.key2 and
        t1.key3 = t2.key3 and
        datediff(t1.date, t2.date) between -5 and 5

РЕДАКТИРОВАТЬ:

Если приведенное выше не работает, то, возможно, вы можете переписать запрос как union all:

select . . . 
from t1 join
     t2
     on t1.key1 = t2.key1 and
        t1.key2 = t2.key2 and
        t1.key3 = t2.key3
where datediff(t1.date, t2.date) between -5 and 5
union all
select . . .
from t1
where not exists (select 1
                  from t2
                  where t1.key1 = t2.key1 and
                        t1.key2 = t2.key2 and
                        t1.key3 = t2.key3 and
                        datediff(t1.date, t2.date) between -5 and 5
                 )
union all
select . . .
from t2
where not exists (select 1
                  from t1
                  where t1.key1 = t2.key1 and
                        t1.key2 = t2.key2 and
                        t1.key3 = t2.key3 and
                        datediff(t1.date, t2.date) between -5 and 5
                 );

Я не уверен на 100%, что Hive также примет эти условия корреляции.

0 голосов
/ 26 февраля 2020

Вот мое решение моего собственного вопроса, основанное на предложении @Gordon Linoff, показанном в сеансе обсуждения.

create table t3 as
select *, row_number () over () as id from t1;

create table t4 as
select *, row_number () over () as id from t2;

create table t5 as
select 
  t1.id as id_1
, t1.key1 as key1_1
, t1.key2 as key2_1
, t1.key3 as key3_1
, t1.date as date_1
, t1.v1
, t2.id as id_2
, t2.key1 as key1_2
, t2.key2 as key2_2
, t2.key3 as key3_2
, t2.date as date_2
, t2.v2
from t3 as t1 
full outer join t4 as t2
on t1.key1 = t2.key1 and t1.key2 = t2.key2 and t1.key3 = t2.key3 
where datediff(t1.date, t2.date) between -5 and 5
;

set hive.mapred.mode=nonstrict;
create table t6 as
select
  t1.id as id_1
, t1.key1 as key1_1
, t1.key2 as key2_1
, t1.key3 as key3_1
, t1.date as date_1
, t1.v1
, null as id_2
, null as key1_2
, null as key2_2
, null as key3_2
, null as date_2
, null as v2
from t3 as t1 
where t1.id not in (select t2.id_1 from t5 as t2 where t2.id_1 is not null)
;

create table t7 as
select
  null as id_1
, null as key1_1
, null as key2_1
, null as key3_1
, null as date_1
, null as v1
, t1.id as id_2
, t1.key1 key1_2
, t1.key2 key2_2
, t1.key3 key3_2
, t1.date date_2
, t1.v2
from t4 as t1 
where t1.id not in (select t2.id_2 from t5 as t2 where t2.id_2 is not null)
;

create table t8 as
select * from t5 union all
select * from t6 union all
select * from t7
;
0 голосов
/ 25 февраля 2020

Проблема, как вы уже поняли, заключается в том, что where заставляет t1.date и t2.date существовать. Вам просто нужно избежать этого предположения, например:

(t1.date is null) or (t2.date is null) or (datediff(t1.date, t2.date) between -5 and 5)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...