0

例如,假设我在 PostgreSQL(高于 9.0)中有一个表,其中填充了数据:

row_id    percent    isrc
1         100        123iee43
2         100        1234wr32
3         98         123iee43
4         99         1234wr32
5         95         12313be3
6         99         12313be3
7         96         12313be3

我希望我的结果包含按列分组的所有上述行isrc,然后按percent降序排列的整个组。所以结果应该是这样的:

row_id    percent    isrc
1         100        123iee43
3         98         123iee43
2         100        1234wr32
4         99         1234wr32
6         99         12313be3
7         96         12313be3
5         95         12313be3

如果我想要升序,这就是我所期望的(我只想按一个组中的第一行排序,一个组中的其他行无关紧要):

row_id    percent    isrc
6         99         12313be3
7         96         12313be3
5         95         12313be3
1         100        123iee43
3         98         123iee43
2         100        1234wr32
4         99         1234wr32

我想我必须以某种方式使用窗口函数,但如果存在则无法找到正确的解决方案。此外,如果解决方案尽可能优雅,那就太好了。:)

4

2 回答 2

2

窗口功能

SELECT row_id, percent, isrc
FROM   tbl
ORDER  BY max(percent) OVER(PARTITION BY isrc) DESC, isrc, percent DESC;

聚合函数max()可以用作窗口函数。我不在ORDER BYwindow 子句中使用,因为根据文档

当聚合函数用作窗口函数时,它聚合当前行窗口框架内的行。与默认窗口框架定义一起使用的聚合ORDER BY会产生“运行总和”类型的行为,这可能是也可能不是想要的。要获得整个分区的聚合,请省略ORDER BY或使用 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING. 可以使用其他框架规格来获得其他效果。

WHEREor子句中不能使用窗口函数HAVING,因为它们是在窗口函数之前应用的。但是您可以ORDER BY子句中使用一个,它最后应用(即使在 之后DISTINCT,但在 之前LIMIT)。

窗口函数可能很昂贵,但是这个函数大大简化了查询,它甚至可能比其他方法更快。
而且它肯定是最优雅的。

聚合函数

JOIN。可能会或可能不会更快。

SELECT row_id, percent, isrc
FROM   tbl
JOIN  (SELECT isrc, max(percent) AS max_pct FROM tbl GROUP BY 1) x USING (isrc)
ORDER  BY x.max_pct DESC, isrc, percent DESC;

DISTINCT ON

非常类似于使用聚合函数。

SELECT t.*
FROM   tbl t
JOIN  (
    SELECT DISTINCT ON (isrc) isrc, percent
    FROM   tbl
    ORDER  BY isrc, percent DESC
    ) s USING (isrc)
ORDER BY s.percent DESC, s.isrc, t.percent DESC

这里不需要窗口函数。

SQL Fiddle演示了上述所有内容。

于 2013-04-05T16:45:25.817 回答
0

SQL小提琴

select t.*
from
    t
    inner join (
        select distinct on (isrc) isrc,
            row_number() over(order by percent desc) rn
        from t
        order by isrc, percent desc
    ) s on t.isrc = s.isrc
order by s.rn, t.percent desc
于 2013-04-05T15:31:30.607 回答