在 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 |
+-----+------------+-----------+
这是我的数据集:
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 |
+-----+------------+-----------+