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

在BigQuery中排除单列去重,能否不使用row_number()实现?

BigQuery无需row_number()的多列去重方案(保留最小a值行)

当然可以不用row_number()实现你的需求,以下是几种实用方案,针对30列宽表中基于除a外29列去重、保留每组a值最小行的场景:

方案一:GROUP BY + 聚合函数

核心逻辑是把判定重复的列(除a外的29列)作为分组键,每组内取最小的a值,其他列因分组后本身一致,直接保留即可。

with
  t1 as (
    select 1 as a, 2 as b, 3 as c, 4 as d, 5 as e, 6 as f, 7 as g, 8 as h, 9 as i union all
    select 2 as a, 3 as b, 3 as c, 4 as d, 5 as e, 6 as f, 7 as g, 8 as h, 9 as i union all
    select 3 as a, 4 as b, 3 as c, 4 as d, 5 as e, 6 as f, 7 as g, 8 as h, 9 as i union all
    select 4 as a, 5 as b, 3 as c, 4 as d, 5 as e, 6 as f, 7 as g, 8 as h, 9 as i union all
    select 5 as a, 6 as b, 3 as c, 4 as d, 5 as e, 6 as f, 7 as g, 8 as h, 9 as i union all
    select 6 as a, 2 as b, 3 as c, 4 as d, 5 as e, 6 as f, 7 as g, 8 as h, 9 as i
  )
SELECT 
  MIN(a) AS a,
  b, c, d, e, f, g, h, i
FROM t1
GROUP BY b, c, d, e, f, g, h, i;

这个方案逻辑直观,大数据量下性能稳定,是BigQuery优化较好的操作类型。

方案二:DISTINCT ON(BigQuery标准SQL支持)

DISTINCT ON会按指定列分组,保留每组中ORDER BY排序后的第一行。这里按去重列分组,再按a升序排列,就能自动保留每组a值最小的行。

with
  t1 as (
    select 1 as a, 2 as b, 3 as c, 4 as d, 5 as e, 6 as f, 7 as g, 8 as h, 9 as i union all
    select 2 as a, 3 as b, 3 as c, 4 as d, 5 as e, 6 as f, 7 as g, 8 as h, 9 as i union all
    select 3 as a, 4 as b, 3 as c, 4 as d, 5 as e, 6 as f, 7 as g, 8 as h, 9 as i union all
    select 4 as a, 5 as b, 3 as c, 4 as d, 5 as e, 6 as f, 7 as g, 8 as h, 9 as i union all
    select 5 as a, 6 as b, 3 as c, 4 as d, 5 as e, 6 as f, 7 as g, 8 as h, 9 as i union all
    select 6 as a, 2 as b, 3 as c, 4 as d, 5 as e, 6 as f, 7 as g, 8 as h, 9 as i
  )
SELECT DISTINCT ON (b, c, d, e, f, g, h, i)
  *
FROM t1
ORDER BY b, c, d, e, f, g, h, i, a ASC;

注意:DISTINCT ON后的列必须和ORDER BY的前几列完全匹配,这个方案代码更紧凑,适合需要保留所有列的场景。

方案三:EXISTS子查询

通过子查询找到每组(按去重列)的最小a值,再筛选原表中a等于该最小值的行。

with
  t1 as (
    select 1 as a, 2 as b, 3 as c, 4 as d, 5 as e, 6 as f, 7 as g, 8 as h, 9 as i union all
    select 2 as a, 3 as b, 3 as c, 4 as d, 5 as e, 6 as f, 7 as g, 8 as h, 9 as i union all
    select 3 as a, 4 as b, 3 as c, 4 as d, 5 as e, 6 as f, 7 as g, 8 as h, 9 as i union all
    select 4 as a, 5 as b, 3 as c, 4 as d, 5 as e, 6 as f, 7 as g, 8 as h, 9 as i union all
    select 5 as a, 6 as b, 3 as c, 4 as d, 5 as e, 6 as f, 7 as g, 8 as h, 9 as i union all
    select 6 as a, 2 as b, 3 as c, 4 as d, 5 as e, 6 as f, 7 as g, 8 as h, 9 as i
  )
SELECT t.*
FROM t1 t
WHERE a = (
  SELECT MIN(a)
  FROM t1
  WHERE b = t.b 
    AND c = t.c 
    AND d = t.d 
    AND e = t.e 
    AND f = t.f 
    AND g = t.g 
    AND h = t.h 
    AND i = t.i
);

这个方案适合不熟悉GROUP BY或DISTINCT ON的场景,但列数较多时,子查询里的匹配条件会比较冗长。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 04:35:36