ORDER BY 通过表 IMPALA 之间

Posted

技术标签:

【中文标题】ORDER BY 通过表 IMPALA 之间【英文标题】:ORDER BY through between table IMPALA 【发布时间】:2018-12-04 12:39:19 【问题描述】:

我正在寻找 Impala Query 的想法。

让我试着解释一下我的问题:这完全是关于对 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

希望你能理解

【问题讨论】:

你必须有第二个表格吗?可以改吗。。另外,链的第一个和最后一个条目是什么样的?没有先前条目的 sub 的 begin_id 是什么? sub_ID 排序多久更改一次? 【参考方案1】:

我认为您必须分两步执行此操作 - 首先对排序顺序进行排序,然后进行实际查询。我怀疑获得排序顺序可能会很昂贵(我想不出一种不循环或递归的方法),所以如果可能的话,你应该避免比你必须更频繁地这样做。如果您的 table2 不经常更改,并且您可以更改设计,我会很想将该表中的实际排序顺序存储在一个额外的列中。

任何时候 table2 被修改,您必须在再次运行此查询之前更新排序顺序。因为要更新排序顺序可能需要多次 table2 编辑,并且顺序实际上会被破坏,直到最后一个,我可能会在表上放置一个触发器来设置一个顺序需要更新的标志。您可以在运行此查询之前检查标志,或在夜间维护运行(以先到者为准)并根据需要更新订单。

如果您无法更改数据库,您可以在每次查询运行之前进行排序,但根据您的数据,它可能会减慢很多速度。

无论如何,要弄清楚排序顺序,您需要为 table2 中的每一行创建一个 orderno(直接更新行,或在单独的临时表中。看起来您在数据中有许多订单列表, 每个 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 需要以这种方式工作,这将让您在一个查询中完成所有操作。

【讨论】:

以上是关于ORDER BY 通过表 IMPALA 之间的主要内容,如果未能解决你的问题,请参考以下文章

MariaDB - CONNECT ENGINE - ORDER BY 错误

order by 与group by 之间排序问题

在 where 子句和 order by 子句之间的 MySQL 索引

mysql中order by分别 按两张表相同的属性排序为啥结果不一样

impala进阶学习

一次 group by + order by 性能优化分析