You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Hive表Distinct不同用法查询结果差异问题咨询

问题结论

你前两条查询里对DISTINCT的使用确实存在逻辑错误,三个查询结果不一致不是Hive执行bug,是不同SQL的实际执行逻辑完全不同,和你预期的逻辑不匹配。

三条SQL的实际执行逻辑拆解
  • select count(*) from test:直接统计test表的物理总行数,返回2609173是表的真实全量行数,这个结果本身没有问题。
  • select distinct count(*) from test:这里的DISTINCT完全是冗余无效写法。SQL执行顺序是先做聚合计算:全表扫描算出count(*)的单个结果值2609173,生成只有1行1列的中间结果集,再对这个单值结果做去重,单值去重当然还是2609173。这条语句从头到尾没有对test表的原始数据行做任何去重操作。
  • insert into testToo select distinct * from test:这才是真正对test表做全字段去重的逻辑——只要两行数据所有字段的值完全一致,就判定为重复,只保留1条写入testToo。最终插入673065行,说明原表260多万行里存在大量全字段完全重复的数据,整体重复率超过70%。

排查验证步骤
  1. 验证原表重复数据是否符合预期,执行分组统计SQL看重复分布:
    -- 注意:低版本Hive不支持group by *,需要手动替换成test表的所有字段名
    select 
        repeat_cnt,
        count(*) as row_group_cnt
    from (
        select 
            *,
            count(*) as repeat_cnt
        from test
        group by 字段1,字段2,字段3 -- 替换为test表全部字段,和select *的列一一对应
    ) t
    group by repeat_cnt
    order by repeat_cnt desc;
    
    执行后把repeat_cnt * row_group_cnt的结果累加,总和应该等于2609173,就能确认重复数据的判断完全正确。
  2. 匹配你的实际需求修正SQL写法:
    • 如果要统计全字段去重后的总行数,不要写前两种错误写法,正确写法如下,执行结果应该和testToo的行数673065一致:
      select count(*) from (select distinct * from test) t;
      
    • 如果只需要按某几个字段(比如主键)去重统计,不要用distinct *,直接把去重字段放到count(distinct 字段名)里即可,比如按user_id去重统计用户数就写select count(distinct user_id) from test。
  3. 验证插入结果正确性:执行select count(*) from testToo确认行数确实为673065,排除testToo表提前存在历史数据、插入时字段映射错位的问题。

常见误区提醒

DISTINCT的作用范围是它后面紧跟的所有列的组合,且执行时机是在它所属的查询层级结果生成之后:如果写在聚合函数外层,只会对聚合完成后的结果去重,不会影响聚合前的原始行计算逻辑。

内容的提问来源于stack exchange,提问作者John Stud

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 15:00:56