2

Apache Hive では、左側のデータからすべてのデータを保持し、可能な場合は右側のテーブルからデータを追加して、左結合したいテーブルを作成する必要があります。結合は 2 つのフィールド (material_id と location_id) に基づいているため、このために 2 つの結合を使用します。これは、従来の 2 つの左結合で問題なく機能します。

SELECT 
   a.*, 
   b.*
FROM a
INNER JOIN (some more complex select) b
   ON a.material_id=b.material_id 
   AND a.location_id=b.location_id;

location_id の場合、データベースには 1 と 2 などの 2 つの異なる値しか含まれていません。

「完全一致」がない場合、これは、material_id のみを結合でき、location_id の結合に material_id と location_id の正しい組み合わせ (例: material_id=100 と location_id=1) がないことを意味するという要件があります。 b テーブルでは、結合は location_id の他の可能な値 (例: material_id=001 と location_id=2) に「デフォルト」または「フォールバック」する必要があります。これは、location_id の場合にのみ当てはまります。

CASE などについても可能な限りの回答を検討してきましたが、うまくいきませんでした。みたいなセットアップ

...
ON a.material_id=b.material_id AND a.location_id=
CASE WHEN a.location_id = b.location_id THEN b.location_id ELSE ...;

私たちは、Hive クエリ言語で実際にどのように実行するかを試みましたが、理解できませんでした。

ご協力ありがとうございました!誰かが賢い考えを持っているかもしれません。

サンプルデータは次のとおりです。

Table a
| material_id | location_id | other_column_a |
| 100         | 1           | 45            |
| 101         | 1           | 45            |
| 103         | 1           | 45            |
| 103         | 2           | 45            |



Table b
| material_id | location_id | other_column_b |
| 100         | 1           | 66            |
| 102         | 1           | 76            |
| 103         | 2           | 88            |


Left - Join Table
| material_id | location_id | other_column_a | other_column_b
| 100         | 1           | 45            | 66
| 101         | 1           | 45            | NULL (mat. not in b)
| 103         | 1           | 45            | DEFAULT TO where location_id=2 (88)
| 103         | 2           | 45            | 88

PS:ここで述べたように、存在するなどは、サブクエリ ON では機能しません。

4

2 に答える 2

0

解決策は、結合せずに左結合しa.location_id = b.location_id、優先順にすべての行に番号を付けることです。次に、row_number でフィルタリングします。以下のコードでは、一致するすべての material_id が結合されるため、結合は最初に行を複製します。次に、row_number()関数は、存在する場合は a.location_id = b.location_id行where に 1 を割り当て、存在しない場合は行 1 に 1 を割り当てます。row_number() 関数に追加されるため、正確に一致するものがない場合に、より低い行が「優先」されます。あなたがその考えをつかんだことを願っています。 a.location_id <> b.location_ida.location_id = b.location_idb.location_idorder byb.location_id

select * from 
(
SELECT 
   a.*, 
   b.*,
   row_number() over(partition by material_id 
                     order by CASE WHEN a.location_id = b.location_id THEN 1 ELSE 2 END, b.location_id ) as rn
FROM a
LEFT JOIN (some more complex select) b
   ON a.material_id=b.material_id 
)s 
where rn=1
;
于 2016-09-27T07:47:35.957 に答える
0

多分これは将来誰かに役立つでしょう:

また、別のアプローチも考え出しました。

まず、別のテーブルを作成して、すべての (!) ロケーションの material_id に基づいてテーブル b から平均を計算します。

次に、結合テーブルに 3 つの列を作成します: c1 - material_id と location_id が一致する値 (テーブル a とテーブル b の左結合の結果)。完全一致がない場合、この列は null になります。

c2 - この material_id の平均 (フォールバック) テーブルの数値を書き込むテーブルの値 (場所に関係なく)

c3 - 「実際の値」列。case ステートメントを使用して、列 1 が NULL の場合 (材料と場所が完全に一致しない場合)、列 2 の値 (他のすべての場所の平均) を使用します。さらなる計算のために。

于 2016-09-29T09:39:15.983 に答える