仅返回GROUPING SETS查询中每个组的前n个结果

时间:2017-02-28 15:56:19

标签: sql postgresql

我有一个相当复杂的查询使用GROUPING SETS执行一些聚合,它看起来大致如下:

<script>
    var it = new FormData( document.getElementById('form-id') ).entries();
    var current = {};
    while ( ! current.done ) {
        current = it.next();
        console.info( current )
    }
</script>

一般来说,只要每组的结果数量相当小,这种效果就会很好。但是我在此查询中有一些列可能包含大量不同的值,这会导致此查询返回大量行。

我实际上只对分组集中每个组的最高结果感兴趣。但似乎没有一种明显的方法来限制使用分组集的查询中每组的结果数量,LIMIT在这种情况下不起作用。

我正在使用PostgreSQL 9.6,所以我不会限制我可以在这里使用哪些新功能。

所以我的查询是这样的:

SELECT 
    column1,
    [... more columns here]
    count(*)
FROM table_a 
GROUP BY GROUPING SETS (
    column1,
    [... more columns here]
)
ORDER BY count DESC

我真正想要的只是返回前3个结果:

| column1 | column2 | count |
|---------|---------|-------|
| DE      |         | 32455 |
| US      |         | 3445  |
| FR      |         | 556   |
| GB      |         | 456   |
| RU      |         | 76    |
|         | 12      | 10234 |
|         | 64      | 9805  |
|         | 2       | 6043  |
|         | 98      | 2356  |
|         | 65      | 1023  |
|         | 34      | 501   |

2 个答案:

答案 0 :(得分:2)

使用row_numbergrouping

select a, b, total
from (
    select 
        a, b, total, 
        row_number() over(
            partition by g 
            order by total desc
        ) as rn
    from (
        select a, b, count(*) as total, grouping ((a),(b)) as g
        from t
        group by grouping sets ((a),(b))
    ) s
) s
where rn <= 3

答案 1 :(得分:1)

这样的事情:

WITH T(column1 , column2, cnt) AS
(
SELECT 'kla', 'k', 10
UNION ALL
SELECT 'kle', 'm', 30
UNION ALL
SELECT 'foo', 'k', 10
UNION ALL
SELECT 'bar', 'm', 30
UNION ALL
SELECT 'bar', 'k', 20
UNION ALL
SELECT 'foo', 'm', 15
UNION ALL
SELECT 'foo', 'p', 10
),
tt AS (select  column1, column2, COUNT(*) AS cnt from t GROUP BY GROUPING SETS( (column1), (column2))  )

(SELECT column1, NULL as column2, cnt FROM tt WHERE column1 IS NOT NULL ORDER BY cnt desc LIMIT 3)
UNION ALL
(SELECT NULL as column1, column2, cnt FROM tt WHERE column2 IS NOT NULL ORDER BY cnt desc LIMIT 3)