ЗАКАЗАТЬ ПРОЙДИТЕ между таблицей ИМПАЛА - PullRequest
0 голосов
/ 04 декабря 2018

Я ищу идею Impala Query.

Позвольте мне попытаться объяснить мою проблему: все дело в сортировке идентификаторов.У меня есть таблица с разными типами идентификаторов.Идентификатор головы и вид вспомогательных идентификаторов (для одного идентификатора головы может быть до 150 вспомогательных идентификаторов)

Через оконную функцию (ROW_NUMBER() OVER (PARTITION BY)) сортировать их без проблем.Основная проблема в том, что у них есть определенный порядок, который хранится во второй таблице.

Вторая таблица содержит каждые Sub_ID, и какой идентификатор стоит до, а какой после.

Мне это удалосьсортировать эти разделы, а также идентифицировать первый идентификатор, но я понятия не имею, как сортировать по другой таблице.

Давайте попробуем показать вам пример:

таблица 1

head_ID sub_ID
1        001
1        002
1        003
2        011
2        012
2        013
2        014

Таблица 2

sub_ID begin_ID end_ID
002     003      001
012     011      0013

Надеюсь, вы поняли идею

1 Ответ

0 голосов
/ 07 декабря 2018

Я думаю, что вам придется сделать это в два шага - сначала отсортировать порядок сортировки, а затем выполнить реальный запрос.Я подозреваю, что получение порядка сортировки может быть дорогостоящим (я не могу найти способ сделать это, не цикличный или рекурсивный), поэтому, если возможно, вам следует избегать делать это чаще, чем нужно.Если ваша таблица2 меняется не очень часто, и вы можете изменить дизайн, у меня будет соблазн сохранить фактический порядок сортировки в этой таблице в дополнительном столбце.

Каждый раз, когда таблица 2 модифицируется, вам нужно будет обновить порядок сортировки, прежде чем снова выполнить этот запрос.Поскольку для обновления порядка сортировки, вероятно, потребовалось бы несколько правок таблицы2, и порядок фактически был бы нарушен до последнего, я бы, вероятно, поставил на таблицу триггер, чтобы установить флаг, который необходимо обновить.Вы можете проверить флаг перед выполнением этого запроса или в ночном цикле обслуживания (в зависимости от того, что наступит раньше) и при необходимости обновить порядок.

Если вы не можете изменить БД, вы можете выполнить сортировку докаждый запрос выполняется, но в зависимости от ваших данных это может сильно замедлить процесс.

В любом случае, чтобы выяснить порядок сортировки, вам нужно создать orderno для каждой строки в table2 (либо обновить строки напрямую,или в отдельной временной таблице. Похоже, у вас есть несколько списков заказов в данных, по одному для каждого headerID. Вы можете создать заказ, сначала найдя начальную строку для каждой цепочки (я предполагаю, что begin_ID равен нулю),и присвойте им orderNo 1. Затем в цикле найдите строки, которые должны быть следующими orderno, и распределите их по ним, пока вы не найдете больше. Если у вас есть строки в конце, которые не имеютЕсли вы не разместите orderNo, у вас возникнут проблемы с данными.

--Set up the work table
DECLARE @Work TABLE (Sub_ID int, orderNo int);

-- Set up the start of each order list
insert into @Work (sub_ID, orderNo)
Select sub_ID, 1
from table2 
where begin_ID is null;

DECLARE @Finished int = 0;  --Flag to see if we're done
DECLARE @NextOrder int = 2; --Next order number to process

While @Finished = 0
BEGIN
    -- add the next level for all the order lists
    insert into @Work (sub_ID, orderNo)
    Select t2.sub_ID, @NextOrder
    From table2 t2
        inner join @Work w on w.sub_ID = t2.begin_ID       -- We want rows that are next in an order chain
        left outer join @Work w2 on w2.sub_ID = t2.sub_ID  -- and haven't already been done (to avoid loops)
    Where w2.Sub_ID is null;

    IF @@ROWCOUNT = 0 SET @Finished = 1;  --flag if nothing was updated (so stop)
    SET @NextOrder = @NextOrder + 1;  -- next order level to add
END;

--example usage of order table.  Note that any records where w.sub_id is null means
-- that record was not in a reachable order list (either the table2 record does not
-- exist, or the order list walk never reached it).
Select t1.*
from table1 t1
    left outer join @Work w on w.sub_ID = t1.sub_id
order by T1.head_id, w.orderNo

Вы также можете сделать это с помощью рекурсивного CTE, но теория будет такой же.Если вам нужно, чтобы IMPALA работала таким образом, я позволю вам сделать все это одним запросом.

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