SQL: таблица к таблице ключ-значение - PullRequest
2 голосов
/ 21 апреля 2020

У меня есть таблица в HIVE, например:

A    | B   | C  | value
key1 |NULL|NULL| v1
NULL | key2  |NULL| v2
NULL |NULL| key3  | v3
NULL | key4  |NULL| v4

Какой самый простой способ преобразовать ее в некоторую таблицу значений ключей, например:

key_type | key_value | value
A | key1 | v1
B | key2 | v2
C | key3 | v3
B | key4 | v4

, используя Hive- SQL или преобразование Spark Dataframe (PySpark)? Спасибо за любую помощь.

Ответы [ 3 ]

1 голос
/ 21 апреля 2020

Используя pyspark, вы можете использовать greatest после фильтрации необходимых столбцов и возврата имен столбцов, когда значение столбца не равно нулю:

import pyspark.sql.functions as F

cols = [i for i in df.columns if i!='value'] #['A','B','C']

output = df.select(F.greatest(*[F.when(F.col(i).isNotNull(),i)
                             for i in cols]).alias("key_type")
               ,F.greatest(*[F.col(i) for i in cols]).alias("key_Value"),"value")

output.show()

+--------+---------+-----+
|key_type|key_Value|value|
+--------+---------+-----+
|       A|     key1|   v1|
|       B|     key2|   v2|
|       C|     key3|   v3|
|       B|     key4|   v4|
+--------+---------+-----+
1 голос
/ 21 апреля 2020

Еще один способ сделать это . используя pyspark.sql.functions.coalesce

from pyspark.sql import functions as F

df.withColumn("key",F.coalesce(*[(F.when(F.col(x).isNotNull(),F.array(F.lit(x),F.col(x)))).alias(x)\
                                 for x in df.columns if x!='value']))\
  .select((F.col("key")[0]).alias("key_type"),(F.col("key")[1]).alias("key_value"),F.col("value")).show()

#+--------+---------+-----+
#|key_type|key_value|value|
#+--------+---------+-----+
#|       A|     key1|   v1|
#|       B|     key2|   v2|
#|       C|     key3|   v3|
#|       B|     key4|   v4|
#+--------+---------+-----+
0 голосов
/ 21 апреля 2020

Вы можете использовать union all:

select t.key_type, t.key_value, t.value
from ( (select 'a' as key_type, a as key_value, value from t) union all
       (select 'b' as key_type, b as key_value, value from t) union all
       (select 'c' as key_type, c as key_value, value from t) 
     ) t
where t.key_type is not null
order by t.value;
...