Estou tentando classificar linhas de uma tabela no PostgreSQL 10.12:
CREATE TABLE example (
id serial PRIMARY KEY,
val text NOT NULL,
x integer NOT NULL,
y integer NOT NULL
);
INSERT INTO example (val,x,y)
VALUES
('First Value (This should be first order)',7,2)
, ('Second Value (This should be second order)',6,3)
, ('Third Value (This should be third order)',5,4)
, ('Seventh Value (And This should be last order)',4,1)
, ('Sixth Value (This should be sixth order)',3,5)
, ('Fifth Value (This should be fifth order)',2,6)
, ('Fourth Value (This should be fourth order)',1,7)
;
As três primeiras linhas de resultados devem ser ordenadas por x desc
, e as demais devem ser ordenadas por y desc
.
Eu tentei esta consulta, mas está ordenando apenas por y
:
SELECT * from (SELECT * from example order by x desc fetch first 3 rows only) foo
UNION
SELECT * from example order by y desc;
Mas classifica apenas por y
. E eu preciso obter o resultado sem UNION
.
Isso retorna as 3 primeiras linhas de acordo com
ORDER BY x DESC
e anexa o restante classificado pory DESC
:TABLE
é apenas um atalho paraSELECT * FROM
.UNION ALL
garante que as duas tabelas derivadas sejam apenas anexadas sem tentar eliminar duplicatas (inexistentes) e, assim, mexer na ordem de classificação.Os parênteses são necessários para que
ORDER BY
se aplique apenasSELECT
entre , não ao conjunto completo de linhas.Ver:
Combine várias instruções SELECT
A ordem é preservada após UNION no PostgreSQL?
Relacionado:
Combinando 2 consultas SELECT e imprimindo os resultados no PostgreSQL
Existe uma maneira mais rápida de obter o comportamento UNION ALL no Postgres?
Sem
UNION
Mesmo resultado.
Os
LEFT JOIN
resultadosc.x
sãoNULL
exceto para as 3 primeiras linhas escolhidas. Portanto, os primeirosORDER BY
itensc.x DESC NULLS LAST
classificam apenas as 3 primeiras linhas e deixam o restante sem classificação. O segundoORDER BY
iteme.y DESC
classifica o restante conforme desejado.Sobre
NULLS LAST
:db<>fique aqui
Se a tabela não for trivialmente pequena, você deve ter um index on
(x)
e outro on(y)
Você pode tentar uma expressão de tabela comum: