2012-07-05 7 views
4

Possible Duplicate:
SQL Query JOIN with TableОбъединение двух таблиц в улье с помощью HiveQL (Hadoop)

CREATE EXTERNAL TABLE IF NOT EXISTS TestingTable1 (This is the MAIN table through which comparisons need to be made) 
(
BUYER_ID BIGINT, 
ITEM_ID BIGINT, 
CREATED_TIME STRING 
) 

И это данные в приведенной выше первой таблице

**BUYER_ID** | **ITEM_ID**  |  **CREATED_TIME** 
--------------+------------------+------------------------- 
1015826235  220003038067  *2001-11-03 19:40:21* 
1015826235  300003861266  2001-11-08 18:19:59 
1015826235  140002997245  2003-08-22 09:23:17 
1015826235  *210002448035*  2001-11-11 22:21:11 

Это вторая таблица в Hive- Он также содержит информацию о предметы, которые мы покупаем.

CREATE EXTERNAL TABLE IF NOT EXISTS TestingTable2 
(
USER_ID BIGINT, 
PURCHASED_ITEM ARRAY<STRUCT<PRODUCT_ID: BIGINT,TIMESTAMPS:STRING>> 
) 

И это данные в приведенной выше второй таблице (TestingTable2) -

**USER_ID** **PURCHASED_ITEM** 
1015826235  [{"product_id":220003038067,"timestamps":"1004941621"}, {"product_id":300003861266,"timestamps":"1005268799"}, {"product_id":140002997245,"timestamps":"1061569397"},{"product_id":200002448035,"timestamps":"1005542471"}] 

Сравнить TestingTable2 с TestingTable1 так, что ниже сценарий выполняется.

Найдите PRODUCT_ID И TIMESTAMPS из TestingTable2 КОТОРЫХ НЕ СООТВЕТСТВИЕ С ITEM_ID И CREATED_TIME от TestingTable1 КОРРЕСПОНДЕНТУ К BUYER_ID(USER_ID) после сравнения с TestingTable1.

Так что если вы посмотрите TestingTable2 данные этого (последнего) ITEM_ID 210002448035 из TestingTable1 не соответствие с TestingTable2PRODUCT_ID- 200002448035 данных и аналогично с временными метками. Поэтому я хочу показать результат ниже, используя запрос HiveQL.

**BUYER_ID** | **ITEM_ID**  |  **CREATED_TIME**   | **PRODUCT_ID** |  **TIMESTAMPS** 
--------------+------------------+--------------------------------+------------------------+---------------------- 
1015826235   *210002448035*   2001-11-11 22:21:11   200002448035   1005542471 
1015826235  220003038067   *2001-11-03 19:40:21*   220003038067   1004941621 

Может ли кто-нибудь помочь мне с этим. Поскольку я новичок в HiveQL, поэтому у меня много проблем.

Обновлено: -

Я написал этот запрос, но он не работает так, как я хотел.

select * from 
    (select * from 
    (select user_id, prod_and_ts.product_id as product_id, prod_and_ts.timestamps as timestamps 
     from testingtable2 LATERAL VIEW 
     explode(purchased_item) exploded_table as prod_and_ts) 
     prod_and_ts 
     LEFT OUTER JOIN testingtable1 
    ON (prod_and_ts.user_id = testingtable1.buyer_id AND testingtable1.item_id = prod_and_ts.product_id 
    AND prod_and_ts.timestamps = UNIX_TIMESTAMP (testingtable1.created_time) 
) 
    where testingtable1.buyer_id IS NULL) 
    set_a LEFT OUTER JOIN testingtable1 
    ON (set_a.user_id = testingtable1.buyer_id AND 
    (set_a.product_id = testingtable1.item_id OR set_a.timestamps = UNIX_TIMESTAMP(testingtable1.created_time)) 
); 

One More UPDATE

Согласно user1166147 комментарии. Я написал свой запрос в соответствии с его запросом. В улье, я думаю, INNER JOIN написано просто JOIN.

Это мой нижний запрос.

select * from (select t2.buyer_id, t2.item_id, t2.created_time as created_time, subq.user_id, subq.product_id, subq.timestamps as timestamps 
from 
(select user_id, prod_and_ts.product_id as product_id, prod_and_ts.timestamps as timestamps from testingtable2 lateral view explode(purchased_item) exploded_table as prod_and_ts) subq JOIN testingtable1 t2 on t2.buyer_id = subq.user_id 
AND subq.timestamps = unix_timestamp(t2.created_time) 
WHERE (subq.product_id <> t2.item_id) 
union all 
select t2.buyer_id, t2.item_id as item_id, t2.created_time, subq.user_id, subq.product_id as product_id, subq.timestamps 
from 
(select user_id, prod_and_ts.product_id as product_id, prod_and_ts.timestamps as timestamps from testingtable2 lateral view explode(purchased_item) exploded_table as prod_and_ts) subq JOIN testingtable1 t2 on t2.buyer_id = subq.user_id 
    and subq.product_id = t2.item_id 
    WHERE (subq.timestamps <> unix_timestamp(t2.created_time))) unionall; 

И после выполнения вышеуказанного запроса я возвращаю нулевой результат.

Заключительное UPDATE: -

My Bad, у меня не было точных данных в таблицах, так что по этой причине я не получаю результат обратно. Да, он обрабатывает фактический выше запрос.

+0

@biziclop, Спасибо за редактирование, Любое предложение, как я могу достичь результата, которого я хочу? – ferhan

+0

Извините, я не эксперт по ульям, может быть, кто-то еще :) – biziclop

+0

Что значит «это не работает», ссылаясь на запрос? Каковы результаты, которые вы получаете? –

ответ

5

EDIT - ЧАСТЬ 1 Хорошо - По какой-то причине, я собираюсь объяснить себя - так, чтобы начать с я наткнулся на этот вопрос, потому что в SQL тега, и увидел куст, и начал не смотреть и просто пропустить Это. НО потом я заметил, что прошло уже больше дня, и у вас не было ответов.Я посмотрел - я увидел коррекцию логики SQL в исходном запросе, опубликованном, который, как я знал, понадобился бы и помог бы, поэтому я опубликовал ТОЛЬКО, потому что никто не ответил. Я постараюсь ответить на этот последний вопрос, но после этого я оставляю свой совет себе, поскольку я могу давать плохие советы. Удачи! Я пытался! И вы, кажется, получать ответы прямо сейчас, так что ...

В TSQL, я мог бы решить эту всю проблему с ниже одного запроса:

SELECT * 
FROM SO_Table1HIVE A 
FULL OUTER JOIN SO_Table2HIVE B ON A.BUYER_ID = B.[USER_ID] AND (B.t1time = A.Created_TIME OR B.PRODUCTID = A.ITEM_ID) 

Было бы вернуть все, в том числе ваш матч buyer_id/user_id. Он не будет соответствовать строке buyer_id/user_id без совпадений ни времени, ни продукта в другой таблице, но он вернет его как отдельную строку с NULLS в полях другой таблицы. Я бы не соглашался с ними в любом случае - нет точной информации, предоставляемой для этого, как описано ниже.

END EDIT ЧАСТЬ 1

Если вы не можете сделать FULL OUTER JOIN с OR в улье, самый простой способ, чтобы удовлетворить первоначальные критерии, чтобы с. В одном из запросов, помимо присоединения к совпадающим user_ids, присоединитесь к PRODUCT_ID И в вашем WHERE найдите TIMESTAMPS, которые не соответствуют CREATED_TIME. Во втором запросе, помимо присоединения к совпадающим user_ids, присоединяйтесь к времени И в своем WHERE найдите продукты, которые не совпадают.

EDIT ЧАСТЬ 2 - ОБНОВЛЕНИЕ ДЛЯ COMMENT ВОПРОС ДОПОЛНИТЕЛЬНОГО КРИТЕРИИ

Если я понимаю, последние критерии это любая запись в любой таблице, которая имеет соответствие user_id = buyer_id, но ничего не соответствует. Условие FULL OUTER JOIN с условием OR вернет их, но информации, предоставленной для сопоставления записей друг с другом, недостаточно. Мы можем легко идентифицировать их, но не можем привязать их друг к другу. Если вы это сделаете, и у вас будет более одной записи без соответствия в любой из обеих таблиц, для каждого из них будет несколько записей.

Любой запрос, который я написал, чтобы попытаться связать их без дополнительной информации (и, вероятно, с), был бы предположением и неточным.

Например, в первой таблице, если были эти 2 (образец поддельные) записи с ничего согласования во втором за исключением user_id:

1015826235 420003038067 2011-11-03 19:40:21.000 
1015826235 720003038067 2004-11-03 19:40:21.000 

И в table2 - это не соответствие:

1015826235 {"product_id":520003038067,"timestamps":"10... 
1015826235 {"product_id":620003038067,"timestamps":"10... 

вы можете идентифицировать их, но если вы соответствуете их без более критериев вы получаете 4 вместо 2:

1015826235 420003038067 2011-11-03 19:40:21.000 1015826235 520003038067 
1015826235 420003038067 2011-11-03 19:40:21.000 1015826235 620003038067 
1015826235 720003038067 2004-11-03 19:40:21.000 1015826235 520003038067 
1015826235 720003038067 2004-11-03 19:40:21.000 1015826235 620003038067 

Мое предложение было бы просто определить их и показать им, как показано ниже.

BUYER_ID  ITEM_ID  CREATED_TIME   USER_ID PRODUCTID timestamps 
---------------------------------------------------------------------- 
NULL   NULL   NULL     1015826235 520003038067 2009-11-11 22:21:11.000 
NULL   NULL   NULL     1015826235 620003038067 2008-11-11 22:21:11.000 
1015826235  420003038067 2011-11-03 19:40:21.000 NULL NULL NULL  
1015826235  720003038067 2004-11-03 19:40:21.000 NULL NULL NULL  

END EDIT ЧАСТЬ 2 - ОБНОВЛЕНИЕ ДЛЯ COMMENT ВОПРОС Дополнительные критерии - ЧАСТЬ 1

Я работаю с TSQL, так что я не могу проверить для вас точный запрос с синтаксисом, но понятия объединений одинаковы, и это вернет то, что вы хотите.Я выполнил ваш запрос и попробовал свой синтаксис, при необходимости изменив его. Я тестировал в TSQL. Вы можете принять это и улучшить его с функциональностью в HiveQL. Есть и другие способы сделать это, но это самое простое, и это переведёт на HiveQL.

REMOVED, ВЫ ПОЛУЧИЛИ ЭТО ЧАСТЬ И ЭТО ВХОДИТ СПУСТЯ

(снова изменить синтаксис при необходимости) **

SELECT * 
FROM (
    SELECT BUYER_ID,ITEM_ID,CREATED_TIME,PRODUCT_ID,TIMESTAMPS 
    FROM testingtable2 LATERAL VIEW 
     explode(purchased_item) exploded_table as prod_and_ts) 
     prod_and_ts 
    INNER JOIN table2 A ON A.BUYER_ID = prod_and_ts.[USER_ID] AND prod_and_ts.timestamps = UNIX_TIMESTAMP (table2.created_time) 
    WHERE prod_and_ts.product_id <> A.ITEM_ID 
    UNION ALL 
    SELECT BUYER_ID,ITEM_ID,CREATED_TIME,PRODUCT_ID,TIMESTAMPS 
    FROM testingtable2 LATERAL VIEW 
      explode(purchased_item) exploded_table as prod_and_ts) 
      prod_and_ts 
    INNER JOIN table2 A ON A.BUYER_ID = prod_and_ts.[USER_ID] AND prod_and_ts.product_id = A.ITEM_ID 
    WHERE prod_and_ts.timestamps <> UNIX_TIMESTAMP (table2.created_time) 
) X 

А вот мой протестирован версия TSQL с моим столом Имена для справки:

SELECT * 
FROM(
    SELECT * 
    FROM SO_Table1HIVE A 
    INNER JOIN SO_Table2HIVE B ON A.BUYER_ID = B.[USER_ID] AND B.t1time = A.Created_TIME 
    WHERE B.PRODUCTID <> A.ITEM_ID 
    UNION ALL 
    SELECT * 
    FROM SO_Table1HIVE A 
    INNER JOIN SO_Table2HIVE B ON A.BUYER_ID = B.[USER_ID] AND B.PRODUCTID = A.ITEM_ID 
    WHERE B.t1time <> A.Created_TIME 
) X 

* EDIT ЧАСТЬ 3 - ОБНОВЛЕНИЕ ДЛЯ КОММЕНТАРИЕВ ВОПРОС ДОПОЛНИТЕЛЬНЫЕ КРИТЕРИИ -часть 2

В TSQL весь запрос (без объединения) могут выполняться с использованием FULL OUTER JOIN с OR условием на объединение

SELECT * 
FROM SO_Table1HIVE A 
FULL OUTER JOIN SO_Table2HIVE B ON A.BUYER_ID = B.[USER_ID] AND (B.t1time = A.Created_TIME OR B.PRODUCTID = A.ITEM_ID) 

Если вы не можете просто сделать это выше, для логики SQL для новых критериев - захватить те, которые не совпадают с обеими таблицами, и отобразить их как NULL в другой таблице, используйте RIGHT JOIN и LEFT JOIN. RIGHT JOIN возьмет что-нибудь в первом столе, спички второго и все во втором, а LEFT делает наоборот. Добавьте новые запросы к вашему UNION.

TSQL Пример - ИЗМЕНИТЬ ДЛЯ энцефалопатии

SELECT * 
FROM SO_Table1HIVE A 
RIGHT JOIN SO_Table2HIVE B ON A.BUYER_ID = B.[USER_ID] AND (B.t1time = A.Created_TIME OR B.PRODUCTID = A.ITEM_ID) 
WHERE A.BUYER_ID IS NULL 
UNION ALL 
SELECT * 
FROM SO_Table1HIVE A 
LEFT JOIN SO_Table2HIVE B ON A.BUYER_ID = B.[USER_ID] AND (B.t1time = A.Created_TIME OR B.PRODUCTID = A.ITEM_ID) 
WHERE B.[USER_ID] IS NULL 

Или, если вы хотите, чтобы захватить их и сопоставить их дубликатами добавить в UNION:

TSQL

SELECT * 
FROM SO_Table1HIVE A 
JOIN SO_Table2HIVE B ON A.BUYER_ID = B.[USER_ID] 
WHERE B.t1time NOT IN(SELECT Created_TIME FROM SO_Table1HIVE) 
AND A.Created_TIME NOT IN(SELECT t1time FROM SO_Table2HIVE) 
AND B.PRODUCTID NOT IN(SELECT ITEM_ID FROM SO_Table1HIVE) 
AND A.ITEM_ID NOT IN(SELECT PRODUCTID FROM SO_Table2HIVE) 

Опять же, Удачи!

+0

Спасибо за подробный ответ. Действительно оценен. Но проблема с 'HiveQL' заключается в том, что она не поддерживает' INNER JOIN' и NOT EQUALITY '<>', поэтому причина в том, что вся проблема подходит для меня. Я попробую это, тогда он покажет мне, что INNER JOIN не поддерживается в настоящее время. [Https://karmasphere.com/hive-queries-on-table-data](https://karmasphere.com/hive-queries-on-table-data). – ferhan

+0

Есть ли способ обойтись без использования 'INNER JOIN' и' <> '? – ferhan

+0

Я думаю, что INNER JOIN работает, я попробовал простой запрос. Я получил некоторый результат. Но когда я написал запрос так, как вы предлагали, я получаю некоторую ошибку. Я отредактировал мой вопрос на ваш ответ, можете ли вы указать мне, что я ошибаюсь, я думаю, некоторые ошибки синтаксиса, я думаю. Я обновил свой вопрос, не могли бы вы посмотреть, что я ошибаюсь? – ferhan

1

Вы, вероятно, нужно использовать Hive transform functionality и иметь собственный редуктор, который делает соответствие между записями из двух таблиц: t1 и t2, где t1 просто TestingTable1 и t2 является

SELECT 
     user_id, 
     prod_and_ts.product_id as product_id, 
     prod_and_ts.timestamps as timestamps 
    FROM 
     TestingTable2 
     LATERAL VIEW explode(purchased_item) exploded_table as prod_and_ts 

as explained by me in another question of yours.

FROM (
    FROM (
     SELECT 
     buyer_id, 
     item_id, 
     created_time, 
     id 
     FROM (
     SELECT 
      buyer_id, 
      item_id, 
      created_time, 
      't1' as id 
     FROM 
      TestingTable1 t1 
     UNION ALL 
     SELECT 
      user_id as buyer_id, 
      prod_and_ts.product_id as item_id, 
      prod_and_ts.timestamps as created_time, 
      't2' as id 
     FROM 
      TestingTable2 
      LATERAL VIEW explode(purchased_item) exploded_table as prod_and_ts 
     )t 
    )x 
     MAP 
     buyer_id, 
     item_id, 
     created_time, 
     id 
     USING '/bin/cat' 
     AS 
     buyer_id, 
     item_id, 
     create_time, 
     id 
     CLUSTER BY 
     buyer_id 
    ) map_output 
    REDUCE 
     buyer_id, 
     item_id, 
     create_time, 
     id 
    USING 'my_custom_reducer' 
    AS 
     buyer_id, 
     item_id, 
     create_time, 
     product_id, 
     timestamps; 

Вышеуказанный запрос состоит из двух отдельных частей. Первая часть - «MAP», а другая - «REDUCE». В промежутке между этими двумя частями находится фаза под названием shuffle (представлена ​​CLUSTER BY buyer_id), которая автоматически заботится о моем улье. Часть карты запроса читается из таблиц, а также передает идентификатор (id, который представляет, из каких таблиц поступает запись). Фаза Shuffle группирует все записи на buyer_id. Фаза «Уменьшение» будет принимать все записи для данного buyer_id и выпускать только записи, соответствующие критериям соответствия.Вам придется написать редуктор самостоятельно на основе ваших соответствующих критериев. Вы можете написать его на любом выбранном вами языке. Гарантируется, что все записи, имеющие тот же самый покупатель_ид, перейдут к одному и тому же сценарию редуктора.

Возможно, это будет более простой способ, но это метод, о котором я могу думать прямо сейчас. Удачи! Чтобы получить дальнейшее понимание того, почему я выбрал этот метод, see my recent answer here.

+0

Спасибо за отличный ответ. Но я получаю ошибку, если я запускаю указанный выше запрос так, как есть. Ошибка - 'FAILED: Ошибка анализа: строка 18:18 не соответствует входному сигналу 't2', ожидающему EOF'. Любое предположение, почему это происходит так? – ferhan

+0

Была небольшая опечатка. Повторите попытку? –

+0

Я попробую это. Спасибо за вашу помощь. – ferhan