我有一张这样的桌子
type Total
A 100
A 123
A 154
A 50
A 54
B 200
B 166
B 423
B 342
B 213
C 520
C 130
C 234
C 512
我想按组选择前3名。我该怎么办?
答案 0 :(得分:2)
您可以尝试使用row_number()
select * from
(
select type, total, row_number() over(partition by type order by total desc) as rn
from tablename
)A
where rn<=3
答案 1 :(得分:2)
行数很好。在BigQuery中执行此操作的一种有趣方法是:
select type,
array_agg(total order by total desc limit 3) as top3
from t
group by type;
这会将值放入数组。
答案 2 :(得分:2)
在大多数[大数据]使用案例中,使用ROW_NUMBER()效果不佳,因为最终会出现资源超过错误。这是因为它要求同一组的所有点都存在于相同/一个节点中,这在数据偏斜的情况下会导致BigQuery中上述错误
选项1
解决此问题的常用方法之一是使用ARRAY_AGG()函数,如下面的示例所示
#standardSQL
SELECT type, total FROM (
SELECT type, ARRAY_AGG(total ORDER BY total DESC LIMIT 3) arr
FROM `project.dataset.table` GROUP BY type
), UNNEST(arr) total
如果要针对您问题中的数据示例运行
#standardSQL
WITH `project.dataset.table` AS (
SELECT 'A' type, 100 total UNION ALL
SELECT 'A', 123 UNION ALL
SELECT 'A', 154 UNION ALL
SELECT 'A', 50 UNION ALL
SELECT 'A', 54 UNION ALL
SELECT 'B', 200 UNION ALL
SELECT 'B', 166 UNION ALL
SELECT 'B', 423 UNION ALL
SELECT 'B', 342 UNION ALL
SELECT 'B', 213 UNION ALL
SELECT 'C', 520 UNION ALL
SELECT 'C', 130 UNION ALL
SELECT 'C', 234 UNION ALL
SELECT 'C', 512
)
SELECT type, total FROM (
SELECT type, ARRAY_AGG(total ORDER BY total DESC LIMIT 3) arr
FROM `project.dataset.table` GROUP BY type
), UNNEST(arr) total
-- ORDER BY type
您将获得预期的结果
Row type total
1 A 154
2 A 123
3 A 100
4 B 423
5 B 342
6 B 213
7 C 520
8 C 512
9 C 234
选项2
但是要考虑真正的大数据,还有另一个有趣的选择-使用APPROX_TOP_SUM()函数,如下例所示
#standardSQL
SELECT type, value AS total FROM (
SELECT type, APPROX_TOP_SUM(total, total, 3) arr
FROM `project.dataset.table` GROUP BY type
), UNNEST(arr)
显然,对于示例数据,其输出与上述相同