Объединить N массивов в один? - PullRequest
2 голосов
/ 10 октября 2019

У меня есть таблица с именем connection, в которой хранятся property_ids и их существующие API-соединения. Свойство может иметь несколько apis на одном и том же connection_id. Свойство также может иметь несколько connection_id с. Порядок важности для apis возрастает, поэтому API 1 имеет более высокую важность, чем API 14.

Учитывая вышесказанное, я пытаюсь выбрать один connection_id для свойство за день. Учитывая приведенные ниже данные:

+------------+-------------+---------------+----------------+
| yyyy_mm_dd | property_id | connection_id |      apis      |
+------------+-------------+---------------+----------------+
| 2019-10-01 |         100 |         123   | ['8']          |
| 2019-10-01 |         100 |         200   | ['16']         |
| 2019-10-01 |         100 |           5   | ['1','2','14'] |
+------------+-------------+---------------+----------------+

Я хочу вернуть следующее (так как connection_id 5 содержит самое низкое API-соединение):

+------------+-------------+---------------+
| yyyy_mm_dd | property_id | connection_id |
+------------+-------------+---------------+
| 2019-10-01 |         100 |           5   |
+------------+-------------+---------------+

Я думал достичь этого, я мог быобъединить массивы и затем отсортировать их по возрастанию, прежде чем выбрать элемент с индексом 0. Однако я чувствую, что это может быть слишком сложно.

В функциях сбора я не вижу никакой функции слияния - https://cwiki.apache.org/confluence/display/Hive/LanguageManual+UDF#LanguageManualUDF-CollectionFunctions.Может быть, этого можно достичь без слияния?

1 Ответ

3 голосов
/ 10 октября 2019

Если вам нужен connection_id с наименьшим apis, тогда вы можете отсортировать массив, а затем взять запись с наименьшим apis [0]

select yyyy_mm_dd, property_id, connection_id
  from
(
 select yyyy_mm_dd, property_id, connection_id, apis,
        row_number() over(partition by yyyy_mm_dd, property_id order by api0 ) rn
   from
      (
       select yyyy_mm_dd, property_id, connection_id, apis, sort_array(apis)[0] as api0
         from mytable
      )s
)s 
where rn=1;

И если массив является строкой, а не целым числом, он не будет работать с сортировкой,Вы можете взорвать массив, привести его к типу int и взять запись с самым низким API:

select yyyy_mm_dd, property_id, connection_id
  from
(
 select yyyy_mm_dd, property_id, connection_id, apis,
        row_number() over(partition by yyyy_mm_dd, property_id order by api ) rn
   from
      (
       select t.yyyy_mm_dd, t.property_id, t.connection_id, t.apis, cast(e.api as int) as api
         from mytable t
              lateral view explode(apis) e as api
      )s
)s 
where rn=1;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...