Несколько левых внешних объединений в Hive - PullRequest
0 голосов
/ 08 января 2019

В Hive у меня есть две таблицы, как показано ниже:

SELECT * FROM p_test; OK p_test.id p_test.age 01 1 02 2 01 10 02 11 Time taken: 0.07 seconds, Fetched: 4 row(s)

SELECT * FROM p_test2; OK p_test2.id p_test2.height 02 172 01 170 Time taken: 0.053 seconds, Fetched: 2 row(s)

Я должен получить возрастные различия между одним и тем же пользователем в таблице p_test. Поэтому я запускаю HiveQL с помощью функции row_number следующим образом:

SELECT * FROM (SELECT *, ROW_NUMBER() OVER(partition by id order by age asc) rn FROM p_test) t1 LEFT JOIN (SELECT *, ROW_NUMBER() OVER(partition by id order by age asc) rn FROM p_test) t2 ON t2.id=t1.id AND t1.rn=(t2.rn+1) LEFT JOIN (SELECT * FROM p_test2) t_2 ON t_2.id = t1.id;

Результат этого:

t1.id t1.age t1.rn t2.id t2.age t2.rn t_2.id t_2.height 01 1 1 NULL NULL NULL 01 170 01 10 2 01 1 1 01 170 02 11 1 NULL NULL NULL 02 172 02 2 2 02 11 1 02 172 Time taken: 60.773 seconds, Fetched: 4 row(s)

Пока все в порядке. Однако, если я переместил условие, которое осталось, соединяет таблицу t1 и таблицу t2 , показанные выше, в последнюю строку, как показано ниже:

SELECT * FROM (SELECT *, ROW_NUMBER() OVER(partition by id order by age asc) rn FROM p_test) t1 LEFT JOIN (SELECT *, ROW_NUMBER() OVER(partition by id order by age asc) rn FROM p_test) t2 LEFT JOIN (SELECT * FROM p_test2) t_2 ON t_2.id = t1.id AND t2.id=t1.id AND t1.rn=(t2.rn+1);

Я получил неожиданный результат следующим образом:

t1.id t1.age t1.rn t2.id t2.age t2.rn t_2.id t_2.height 01 1 1 01 1 1 NULL NULL 01 1 1 01 10 2 NULL NULL 01 1 1 02 11 1 NULL NULL 01 1 1 02 2 2 NULL NULL 01 10 2 01 1 1 01 170 01 10 2 01 10 2 NULL NULL 01 10 2 02 11 1 NULL NULL 01 10 2 02 2 2 NULL NULL 02 11 1 01 1 1 NULL NULL 02 11 1 01 10 2 NULL NULL 02 11 1 02 11 1 NULL NULL 02 11 1 02 2 2 NULL NULL 02 2 2 01 1 1 NULL NULL 02 2 2 01 10 2 NULL NULL 02 2 2 02 11 1 02 172 02 2 2 02 2 2 NULL NULL

Кажется, что условие, которое я перехожу на последнюю строку, больше не работает. Это беспокоит меня долго. Надеюсь, я смогу услышать любые ценные ответы, спасибо всем, кто заранее дает мне ответы.

1 Ответ

0 голосов
/ 08 января 2019

Во втором запросе LEFT JOIN с t2 без условия ON преобразуется в CROSS JOIN. Вот почему у вас есть дублирование. Для id = 01 у вас есть две строки в подзапросе t1 и 2 строки в t2 изначально, это соединение CROSS дает вам 2x2 = 4 строки.

И условие ON работает, но оно применяется только к последнему левому соединению с подзапросом t_2, это условие проверяется только для определения, какие строки объединить в последнем соединении, а не для всех объединений, это не влияет на первый CROSS ПРИСОЕДИНЯЙТЕСЬ (ЛЕВНОЕ СОЕДИНЕНИЕ без ВКЛ) вообще.

Каждое объединение должно иметь собственное условие ON, кроме перекрестных.

См. Также этот ответ о соединениях без поведения условия ON: https://stackoverflow.com/a/46843832/2700344

Кстати, вы можете сделать то же самое без t2 объединения, используя аналитические функции запаздывания или опережения для вычисления значений, упорядоченных по возрасту.

Как это:

lag(height) over(partition by id order by age) - чтобы получить предыдущую высоту

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...