在 impala 中标记特定行

Flag specific lines in impala

这是我的数据集:

IDX  SESSION_ID
1    Null
2    Null
3    Foo
4    Foo
5    Foo
6    Null
7    Bar
8    Bar

如果我的行是新会话,我想添加一个等于 1 的标志列(我通过新会话定义当我通过 IDX 订购时会话 ID 发生变化的事实)

在那种情况下,输出将是:

IDX  SESSION_ID  N_Session
1    Null        1
2    Null        0
3    Foo         1
4    Foo         0
5    Foo         0
6    Null        1
7    Bar         1
8    Bar         0

如何使用 impala sql 来做到这一点? (我想 ANSI SQL 也应该没问题)

试试这个查询:

SELECT t1.IDX,
       t1.SESSION_ID,
       CASE WHEN t1.IDX = 1 OR
                 t1.SESSION_ID IS NULL AND t2.SESSION_ID IS NOT NULL OR
                 t1.SESSION_ID IS NOT NULL AND t2.SESSION_ID IS NULL OR
                 COALESCE(t1.SESSION_ID, 'a') <> COALESCE(t2.SESSION_ID, 'a')
            THEN 1
            ELSE 0 END AS N_Session
FROM yourTable t1
LEFT JOIN yourTable t2
    ON t1.IDX = t2.IDX + 1

这里 table 显示了连接的临时结果应该是什么样子:

IDX  SESSION_ID   IDX2   SESSION_ID2   N_Session
1    Null         NULL   NULL          1            <-- first row, 1
2    Null         1      NULL          0            <-- session values agree, 0
3    Foo          2      NULL          1            <-- values different, 1
4    Foo          3      Foo           0
5    Foo          4      Foo           0
6    Null         5      Foo           1            <-- values different, 1
7    Bar          6      NULL          1
8    Bar          7      Bar           0

应该清楚我们要在以下两种情况之一中将N_Session标记为1:

  • 两个会话ID不一致
  • 两个会话 ID 一致,但该行是第一行(IDX 值为 1)

我的查询之所以冗长,是因为必须处理 NULL 个值。如果我没看错你的逻辑,比较时的两个 NULL 值实际上应该被视为相同的值,使用某些运算符的 Impala SQL 可能不是这种情况。

select  IDX
       ,SESSION_ID

       ,case 
            when    coalesce (SESSION_ID,'') 
                =   lag(coalesce(SESSION_ID,'')) over (order by IDX) 
            then 0 
            else 1 
        end         as N_Session

from    mytable2
;

+-----+------------+-----------+
| idx | session_id | n_session |
+-----+------------+-----------+
| 1   | NULL       | 1         |
| 2   | NULL       | 0         |
| 3   | Foo        | 1         |
| 4   | Foo        | 0         |
| 5   | Foo        | 0         |
| 6   | NULL       | 1         |
| 7   | Bar        | 1         |
| 8   | Bar        | 0         |
+-----+------------+-----------+