2013-03-25 2 views
2

У меня есть таблица значений ключа-значения с третьим столбцом, представляющим некоторый вес. все, что я хочу, - это собрать первые n строк для каждой пары на основе значения веса, спускающегося.выберите верхние 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 
+0

У вас есть уникальный составной индекс (ключ, значение, вес), так что никогда не может быть двух пар ключ-значение, имеющих одинаковый вес? '15391 22877 8, 15391 22877 8' – Tim

+0

@tim, фактически таблица является совокупностью предыдущей таблицы, где там, где только пары ключ-значение, а столбец веса представляет собой количество раз, когда появилась конкретная пара. так что технически все строки различаются – ulkas

ответ

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 
+0

вправо, я хочу найти все верхние значения n для заданного ключа, а не заданную пару. – ulkas

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, использовать совместное rrelated подзапрос:

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 
Смежные вопросы