Ordenação por valor de campo específico primeiro

103

Eu tenho uma tabela com 3 colunas:

id | name | priority
--------------------
 1 | core  |   10
 2 | core  |   9
 3 | other |   8
 4 | board |   7
 5 | board |   6
 6 | core  |   4

Quero ordenar o conjunto de resultados usando, prioritymas primeiro, as linhas que têm, name=coremesmo que tenham prioridade mais baixa. O resultado deve ser parecido com este

id | name | priority
--------------------
 6 | core  |   4
 2 | core  |   9
 1 | core  |   10
 5 | board |   6
 4 | board |   7
 3 | other |   8
Omid
fonte

Respostas:

174

Há também a função MySQLFIELD .

Se você deseja uma classificação completa para todos os valores possíveis:

SELECT id, name, priority
FROM mytable
ORDER BY FIELD(name, "core", "board", "other")

Se você só se importa que o "núcleo" esteja em primeiro lugar e os outros valores não importem:

SELECT id, name, priority
FROM mytable
ORDER BY FIELD(name, "core") DESC

Se você deseja classificar por "núcleo" primeiro e os outros campos na ordem de classificação normal:

SELECT id, name, priority
FROM mytable
ORDER BY FIELD(name, "core") DESC, priority

Existem algumas ressalvas aqui, no entanto:

Em primeiro lugar, tenho quase certeza de que essa é uma funcionalidade somente do mysql - a questão é chamada de mysql, mas nunca se sabe.

Em segundo lugar, preste atenção em como FIELD()funciona: ele retorna o índice baseado em um do valor - no caso de FIELD(priority, "core"), ele retornará 1 se "núcleo" for o valor. Se o valor do campo não estiver na lista, ele retorna zero . É por isso que DESCé necessário, a menos que você especifique todos os valores possíveis.

Nerdmaster
fonte
5
Após cerca de 5 anos, mudei a resposta aceita para esta porque é mais limpa e mais rápida.
Omid de
equivalente db2?
Cybermonk de
Funcionou para mim, gostaria de fazer mais uma pergunta sobre como lidar se a coluna 'prioridade' contiver valores como ex: 'núcleo da terra', 'novo quadro' etc. Aqui a coluna não contém um valor exato, podemos escrever algo como %testemunho%?
Jayanth Suvarna
@JayanthSuvarna: olhando para os documentos FIELD () do MySQL, tenho certeza de que não há nenhuma maneira de avaliar isso como substrings, já que cada argumento tem que ser algum tipo de string. Pode haver algumas funções de manipulação de string que podem ajudar, mas não tenho certeza.
Nerdmaster
Obrigado, cara. Você fez meu dia.
BEingprabhU
94

Geralmente você pode fazer

select * from your_table
order by case when name = 'core' then 1 else 2 end,
         priority 

Especialmente no MySQL, você também pode fazer

select * from your_table
order by name <> 'core',
         priority 

Já que o resultado de uma comparação no MySQL é 0ou 1e você pode classificar por esse resultado.

Juergen d
fonte
1
o que significa 1e 2significa aqui?
Niraj Chauhan
1
Tenho cerca de 3.000 linhas para classificar. No meu caso, a solução de @ Ayman-Hourieh em stackoverflow.com/questions/958627/… leva metade do tempo em comparação com esta solução.
noite de
@nightlyop: Boa. Apenas uma observação: a solução mais rápida é específica do MySQL.
julho de
1e 2são apenas 2 números que uso para classificar os dados. Pode ser 3e 4ou outra coisa.
julho de
E quando há %na WHEREcláusula? Gostou . . . WHERE name LIKE '%sth%' . . .? stackoverflow.com/questions/41303379/…
pilha
6

Uma maneira de dar preferência a linhas específicas é adicionar um grande número à sua prioridade. Você pode fazer isso com uma CASEdeclaração:

  select id, name, priority
    from mytable
order by priority + CASE WHEN name='core' THEN 1000 ELSE 0 END desc

Demo: http://www.sqlfiddle.com/#!2/753ee/1

mellamokb
fonte
5

Isso funciona para mim usando Postgres 9+:

SELECT *
FROM your_table
ORDER BY name = 'core' DESC, priority DESC
Vojtech Vitek
fonte
Importa-se de explicar -1? Erro + versão do Postgres?
Vojtech Vitek
3

Uma maneira é esta:

select id, name, priority from table a
order by case when name='core' then -1 else priority end asc, priority asc
Icaro
fonte
1
Isso não vai perder a ordem das corelinhas?
mellamokb
1
SELECT * FROM cars_new WHERE status = '1' and car_hide !='1' and cname IN ('Executive Car','Saloon','MPV+','MPV5') ORDER BY FIELD(cname, 'Executive Car', 'Saloon','MPV+','mpv5')
meiy arul
fonte
3
Embora seu código possa ser a resposta para a pergunta, é melhor fornecer alguma explicação sobre ele.
Mehraban
0

faça isso:

SELECT * FROM table ORDER BY column `name`+0 ASC

Adicionar +0 significa que:

0, 10, 11, 2, 3, 4

torna-se :

0, 2, 3, 4, 10, 11
Madhuka Dilhan
fonte
Essa técnica serve para transformar uma corda em um número. Não responde à pergunta do OP. (No entanto, sem ver o tipo de dados de priority, não posso dizer se deve fazer parte da solução completa.)
Rick James
0

Usa isto:

SELECT * 
FROM tablename 
ORDER BY priority desc, FIELD(name, "core")
Saquib Azam
fonte