Suponha que eu tenha os seguintes dados:
| f1 | f2 | f3 |
|----|----|----|
| 1 | 1 | 1 |
| 1 | 1 | 5 |
| 1 | 2 | 3 |
| 1 | 2 | 6 |
| 1 | 3 | 4 |
| 1 | 3 | 7 |
| 2 | 1 | 2 |
| 2 | 1 | 22 |
| 2 | 2 | 3 |
| 2 | 2 | 4 |
Existem dois valores máximos de f3 para cada combinação de f1,f2.
Para este exemplo específico, desejo obter os 2 valores mínimos principais por f1 e intervalo (f2 - max(f2) por f1).
Saída de exemplo:
| f1 | RNG| f3 |
|----|----|----|
| 1 |1 -3| 1 |
| 1 |1 -3| 3 |
| 1 |2 -3| 3 |
| 1 |2 -3| 4 |
| 1 |3 -3| 4 |
| 1 |3 -3| 7 |
| 2 |1- 2| 2 |
| 2 |1- 2| 3 |
| 2 |2- 2| 3 |
| 2 |2- 2| 4 |
Para criar o campo RNG não é necessário. Eu apenas adicionei para mostrar que para f1=1
, existem 3 intervalos: 1-3, 2-3, 3-3
criados pelos valores distintos de f2
for f1=1
. Para cada intervalo, desejo calcular os valores mínimos top-k por f1 e intervalo.
SQL Fiddle aqui:
http://sqlfiddle.com/#!15/9ddbb/1
Construir os intervalos pode ser feito por:
SELECT DISTINCT s1.f1,s1.f2 AS range_from ,s2.f2 AS range_to
FROM dbTable s1,
(SELECT f1,MAX(f2) AS f2 FROM dbTable
GROUP BY f1) s2
WHERE s1.f1=s2.f1
ORDER BY s1.f1,s1.f2;
Existe alguma maneira de conseguir isso, sem construir tabelas intermediárias de banco de dados?
Outra maneira, usando a
LATERAL
sintaxe, disponível nas versões 9.3+::Teste no SQLfiddle .
Ou sem o CTE:
Acho que esta consulta está correta:
E parece dar a saída correta no SQL Fiddle :