如何选择只保留符合此条件的行?sql/hive

egdjgwm8  于 2022-11-05  发布在  Hive
关注(0)|答案(2)|浏览(204)

我有一个如下的表:

+-------+------+
|ID     |lang  |
+-------+------+
|1      |eng   |  
|1      |pol   | 
|2      |eng   |  
|3      |gro   |
|3      |eng   |
+-------+------+

我想只保留那些行,如果ID重复,我会保留非“eng”行,因此,例如,我想:

+-------+------+
|ID     |lang  |
+-------+------+
|1      |pol   | 
|2      |eng   |  
|3      |gro   |
+-------+------+

有没有一个快速简洁的方法可以做到这一点?
不知道如何去做这在一个很好的方式来实现上述结果!我正在使用Hive

nkoocmlb

nkoocmlb1#

如果每个id需要一行,那么使用row_number(),partition by id,order by case语句,在该语句中可以有一些自定义的排序逻辑。
例如,下面的row_number将标记rn=1的任何第一个非eng(随机)行(每个ID),相同ID的任何其他行将标记为〉1:2、3、4......并且您可以只筛选那一行。如果您希望优先选择某些语言,请在case表达式中添加更多的case,以便根据语言进行排序,或者您可以在order by中添加其他列或表达式。

select id, lang
  from ( select id, lang,
                row_number() over(partition by id 
                                  order by case when lang != 'eng' then 1 
                                                else 2 
                                            end
                                 ) rn
        from mytable
       ) s
  where rn=1

如果你需要保留同一个id的所有行,但不是'eng',使用dense_rank()rank()代替row_number(),并与上面的over()相同,它会为每个id的lang!='eng'的所有行赋值1。

1u4esq0p

1u4esq0p2#

WITH cte_temp (Id, Lang, Rank) AS
(    
    SELECT 
        Id, Lang,
        DENSE_RANK() OVER (PARTITION BY Id, LANG ORDER BY LANG DESC) AS Rank 
    FROM 
        YourTable
)
SELECT * 
FROM cte_temp 
WHERE rank = 1

相关问题