为每个键值对选择前n行

时间:2013-03-25 13:52:10

标签: mysql sql postgresql

我有一个键值对表,第三列代表一些重量。我想要的是根据权重值为每对选择前n行,降序。

是支持任何自然方式的主流sql技术吗?或者我必须总是包括一些黑客......

示例数据:

key value   weight   
15391   22877   8    
15391   24311   7    
15391   460     7    
22634   22877   6   

我想为每对选择前2行,即结果应为:

15391   22877   8    
15391   24311   7        
22634   22877   6 

2 个答案:

答案 0 :(得分:3)

这在Postgres很容易做到:

select key, value, weight
from (select key, value, weight, row_number() over (partition by key, value order by weight desc) as seqnum
      from t
     ) t
where seqnum <= 2

如果您想要一个适用于MySQL和Postgres的版本,请使用相关子查询:

select key, value, weight
from (select key, value, weight,
             (select count(*) from t t2 where t2.key = t.key and t2.value = t.value and t2.weight >= t.weight
             ) as seqnum
      from t
     ) t
where seqnum <= 2

答案 1 :(得分:3)

我认为您的描述具有误导性,您真正想要的是:

select key, value, weight
from (
    select *,
        row_number() over(partition by key order by weight desc) rn
    from aggregated_table
) s
where rn <= 2
order by weight desc, key

以上内容适用于Postgresql和SQL Server。这将在MySQL中运行,但不适用于SQL Server:

select key, value, (
    select weight
    from aggregated_table
    where key = s.key
    order by weight desc
    limit 1
    ) weight
from aggregated_table
union
select key, value, (
    select weight
    from aggregated_table
    where key = s.key
    order by weight desc
    limit 1 offset 2
    ) weight
from aggregated_table
order by weight desc, key