通过impala表之间的顺序

iyfamqjs  于 2021-06-01  发布在  Hadoop
关注(0)|答案(1)|浏览(555)

我在找一个 Impala 查询的主意。
让我试着解释一下我的问题:它完全是关于排序ID的。我有一个不同类型ID的表。一个头部id和一类子id(一个头部id最多有150个子id)
通过窗口函数( ROW_NUMBER() OVER (PARTITION BY) )把它们分类是没有问题的。主要问题是,它们有一个存储在第二个表中的特定顺序。
第二个表包含 Sub_ID 哪个id在前面,哪个在后面。
我设法对这些分区进行排序,并标识第一个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

我希望你能明白

tquggr8v

tquggr8v1#

我认为您必须分两步来完成这项工作—首先整理排序顺序,然后执行实际查询。我怀疑获取排序顺序可能会很昂贵(我无法找到一种不循环或递归的方法),因此如果可能,您应该避免频繁地执行排序。如果您的table2不经常更改,并且您可以更改设计,那么我会尝试将该表中的实际排序顺序存储在一个额外的列中。
任何时候修改table2时,都必须更新排序顺序,然后才能再次运行此查询。因为要更新排序顺序可能需要多次table2编辑,而且在最后一次编辑之前,排序顺序实际上会被打破,所以我可能会在表上设置一个触发器,以设置顺序需要更新的标志。您可以在运行此查询之前或在夜间维护运行(以先到者为准)中检查标志,并根据需要更新订单。
如果不能更改数据库,可以在每次查询运行之前进行排序,但根据数据的不同,排序速度可能会降低很多。
无论如何,要计算排序顺序,需要为表2中的每一行创建orderno(或者直接更新行,或者在单独的temp表中)。看起来数据中有许多订单列表,每个headerid对应一个。您可以通过首先找到每个链的起始行(我假设begin\u 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需要这样做的话,这可以让您在一个查询中完成所有的操作。

相关问题