sql—获取配置单元查询中分区组的最后一个值,但有其他要求

vxqlmq5t  于 2021-06-26  发布在  Hive
关注(0)|答案(2)|浏览(313)

假设我在一个表中有3列:id,flag,time。标志只能是三者之一:a1、a2、b。

ID  flag    time
1   A1  2016-01-01
1   A2  2016-01-02
1   B   2016-01-03
1   B   2016-01-04
2   A1  2016-01-02
2   B   2016-01-03
2   A2  2016-01-04
2   B   2016-01-05

数据已按时间为每个id排序。现在我想为每个id获取,当标志等于b时,最后一个非b标志,例如:

1   B   2016-01-03  A2  2016-01-02
1   B   2016-01-04  A2  2016-01-02
2   B   2016-01-03  A1  2016-01-02
2   B   2016-01-05  A2  2016-01-04

这在配置单元查询中可能吗?

u2nhd7ah

u2nhd7ah1#

select  id
       ,flag
       ,time
       ,A.flag as A_flag
       ,A.time as A_time

from   (select  id
               ,flag
               ,time

               ,max
                (
                    case 
                        when flag <> 'B' 
                        then named_struct ('time',time,'flag',flag) 
                    end
                ) over
                (   
                    partition by    id 
                    order by        time 
                    rows            unbounded preceding
                )  as A

        from    t
        ) t

where   flag = 'B'
;
+----+------+------------+--------+------------+
| id | flag |    time    | a_flag |   a_time   |
+----+------+------------+--------+------------+
|  1 | B    | 2016-01-03 | A2     | 2016-01-02 |
|  1 | B    | 2016-01-04 | A2     | 2016-01-02 |
|  2 | B    | 2016-01-03 | A1     | 2016-01-02 |
|  2 | B    | 2016-01-05 | A2     | 2016-01-04 |
+----+------+------------+--------+------------+

附笔
我建议不要使用保留字( time )作为列名。
我建议不要使用非描述性的名称,例如 time 用于日期列。

bihw5rsg

bihw5rsg2#

使用 max 窗口函数来获取非b标志的最大运行时间。那么 join 此结果将返回到原始表,以获取对应的最大时间(在给定id的标志b之前)的标志信息。

SELECT X.*,
       T.FLAG
FROM
 (SELECT T.*,
  MAX(CASE WHEN FLAG<>'B' THEN TIME END) OVER(PARTITION BY ID ORDER BY TIME) AS MAX_TIME_BEFORE_B
  FROM T
 ) X
JOIN T ON T.ID=X.ID AND T.TIME=X.MAX_TIME_BEFORE_B
WHERE X.FLAG='B'
``` `Sample Demo` 

相关问题