例如,假设我在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
我想我必须以某种方式使用窗口函数,但如果存在,则无法找到正确的解决方案。此外,如果解决方案尽可能优雅,那将是非常好的。 :)
答案 0 :(得分:2)
SELECT row_id, percent, isrc
FROM tbl
ORDER BY max(percent) OVER(PARTITION BY isrc) DESC, isrc, percent DESC;
聚合函数max()
可用作窗函数。我不在窗口子句中使用ORDER BY
,因为per documentation:
当聚合函数用作窗口函数时,它会聚合 在当前行的窗口框架内的行上。使用的聚合 使用
ORDER BY
并且默认窗口框架定义生成一个 “运行总和”类型的行为,可能是也可能不是想要的。 要获得整个分区的聚合,请省略ORDER BY
或使用ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
。其他框架 规范可用于获得其他效果。
窗口函数不能在WHERE
或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
你不需要一个窗口功能。
答案 1 :(得分:0)
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