【问题标题】:How to solve a gap-and-islands problem with a high volume set of data in Impala如何在 Impala 中使用大量数据解决差距和孤岛问题
【发布时间】:2019-11-19 17:48:19
【问题描述】:

在 Impala 表中有一个类型 2 维度,大约 500M 行有 102 列:(C1、C2、...、C8、...C100、Eff_DT、EXP_DT) 只需要选择具有 (C1,C2,..,C8) 的不同组合值的行。 对于每个选定的记录,EFF_DT 和 EXP_DT 必须分别是该记录所属组的 min(eff_dt) 和 max(eff_dt)(此处的组由不同的组合定义 (C1,C2,..,C8)

一个简单的 Group By 并不能解决这里的问题,因为它会忽略同一组的时间滞后...

为简单起见,这里是必需的和我尝试过的 - 假设只有 2 列定义一个组(不是 8 ) 以下是仅使用 group by ... 的输入、期望输出和输出示例。

--INPUT                              --DESIRED OUTPUT                     --OUTPUT of SIMPLE GROUP BY
------------------------------------------------------------------------------------------------------------ 
C1  C2  EFF_DT      EXP_DT           C1   C2  Eff_dt      EXP_DT          C1   C2  EFF_DT       EXP_DT
4   8   2013-11-30  2014-01-22       4    8   2013-11-30  2014-01-22      4    8   2013-11-30   2999-12-31
2   8   2014-01-23  2014-01-23       2    8   2014-01-23  2014-01-23      2    8   2014-01-23   2014-01-23
4   8   2014-01-24  2015-12-31       4    8   2014-01-24  2999-12-31
4   8   2016-01-01  2016-12-31
4   8   2017-01-01  2018-03-15
4   8   2018-03-16  2018-07-24
4   8   2018-07-25  2999-12-31

尝试在 select 语句中使用子查询来根据当前行选择 max(exp_dt),但由于 impala 不支持它,所以没有工作.....

这是我尝试过的查询,它工作正常,但在 Impala 中不行(因为 select 语句中不支持子查询

SELECT    
     T0.C1,
     T0.C2,
     MIN(T0.EFF_DT) AS MIN_EFF_DT,
     T0.EXP_DT
FROM (
    SELECT 
    T1.C1,
    T1.C2,
    T1.EFF_DT,
    (
        SELECT MAX(T2.EXP_DT)
        FROM (select * from TABLE_NAME ) T2
        WHERE T2.C1 = T1.C1
        AND   T2.C2 = T1.C2
        AND NOT EXISTS (
        SELECT 1 FROM (select * from TABLE_NAME) T3
            WHERE T3.EXP_DT < T2.EXP_DT 
            AND   T3.EXP_DT > T1.EXP_DT
            AND  (T3.C1 <> T2.C1 OR T3.C2 <> T2.C2 )
        )

    ) EXP_DT
    FROM (select * from TABLE_NAME) T1
) T0 
GROUP BY 
T0.C1,
T0.C2,
T0.EXP_DT
ORDER BY MIN_EFF_DT ASC

【问题讨论】:

  • 我有点困惑。您的行似乎在一个或多个维度上平铺。哪些列定义了“平铺”(即下一个有效日期和结束日期的位置)?哪些定义了数据列?
  • 定义分离的列是 C1,C2,C3,...,C8 我会表述问题:在类型 2 维度中,每次更改任何列时,都会有一条新记录它是为相同的 id 创建的,具有新的值和新的 eff_dt 和 exp_dt 8 列 C1,...C2 ...
  • .... C8 您建议的解决方案完全按预期工作,但有一个问题:不适用于大容量,有许多列(而不仅仅是 C1..C2)
  • 。 .我怀疑您是否有 500,000,000 行的有效日期和结束日期不重叠——所涉及的时间跨度最多可能只有几秒钟。
  • 是 - 存在重叠的 eff 和 exp 日期。时间跨度大致以天为单位(该表涵盖了 2013 年的数据,其中一些仍然有效......)

标签: sql impala


【解决方案1】:

在修改 id 列时,以前的解决方案很可能会起作用:

select id, c1, c2, min(eff_dt), max(exp_dt)
from (select t.*,
             row_number() over (partition by id order by eff_dt) as seqnum,
             row_number() over (partition by id, c1, c2 order by eff_dt) as seqnum_1
      from t
     ) t
group by id, c1, c2, (seqnum - seqnum_1);

您应该能够随心所欲地扩展列数。

【讨论】:

  • 只有当原始数据中没有间隙时才会按预期工作(意味着所有 (eff_dt,exp_dt) 都是连续的,没有整体......当有一个整体时(意味着从 x 到y 什么都没有发生,换句话说,如果你有一行 exp_dt = date_x 并且下一行有 eff_dt = date_x+y days ( y >1 day) ...
  • @SnowWhite 。 . .这就是这个问题中数据的样子。如果您有一个不同的问题,我建议您将其作为一个问题提出,并清楚数据异常。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多