Order by Ninja!

Dúvidas, dicas e truques de PL/SQL. Aqui também vão assuntos relacionados a pacotes, triggers, funções, Java-Stored Procedures, etc
Responder
numerus
Rank: Analista Júnior
Rank: Analista Júnior
Mensagens: 71
Registrado em: Seg, 23 Mai 2011 11:56 am
Localização: SP

Bom dia galera.

então preciso ordenar varias linhas em uma tabela, mas de um jeito diferente, segue exemplo.

Colunas: Campo 1 || Campo 2 || Campo 3 || Campo 4
Dados: 2 4 3 1
Dados: 3 5 2 4

Prreciso retornar na horizontal assim:

1 - 2 - 3 - 4
2 - 3 - 4 - 5

alguém conhece um jeito para fazer isso?

abraços,
gfkauer
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 389
Registrado em: Ter, 27 Jul 2010 1:34 pm
Localização: Sapiranga - RS
Contato:
Quem falou que programar era fácil??

Quanto mais dificil for a implementação mais valorizado seu trabalho será!

Acessem: www.gfkauer.com.br

A ordem das colunas tu só conseguira alterar com cursores dinamicos... ou estruturas que avaliassem cada uma das informações m tempo de esxcecução... mas não seria nada performatico... eu acho
marcus.kobel
Rank: Programador Sênior
Rank: Programador Sênior
Mensagens: 45
Registrado em: Qui, 12 Mai 2011 4:54 pm
Localização: Porto Alegre - RS

Usa, CASE meu filho.
Vai ficar um lixo total a tua query, mas vai funcionar.

CASE
WHEN campo1 < campo2 AND campo1 < campo3 AND campo1 < campo4 THEN campo1
WHEN campo2 < campo3 AND campo2 < campo4 THEN campo2
WHEN campo3 < campo4 THEN campo4
ELSE campo4
END AS coluna1

Repete esse código pra todas as colunas, deve resolver.
Vai ficar um LIXO o teu SQL, mas não vejo uma solução muito melhor.
Senão mete um código PL/SQL. É a melhor solução.
ishii
Rank: Analista Júnior
Rank: Analista Júnior
Mensagens: 82
Registrado em: Ter, 28 Dez 2010 7:41 pm
Localização: São Paulo - SP

Olá,

Challenge accepted!!

Se for Oracle 11 apenas...

Selecionar tudo

create table TESTE
(
  C1   NUMBER,
  C2   NUMBER,
  C3   NUMBER,
  C4   NUMBER,
  LINE VARCHAR2(2)
)
A coluna LINE está como varchar para diferenciar as linhas (a,b,c etc) da numeração a ser ordenada.

Selecionar tudo

insert into teste
values
(4,3,2,1,'a');

insert into teste
values
(2,3,1,4,'b');

insert into teste
values
(7,6,8,1,'c');

commit;

Selecionar tudo

SQL> select * from teste;
 
        C1         C2         C3         C4 LINE
---------- ---------- ---------- ---------- ----
         4          3          2          1 a
         2          3          1          4 b
         7          6          8          1 c
Agora o SQL fantástico:

Selecionar tudo

select line, listagg(dado,' - ') within group (order by line) dado_ordem from 
(select dado,  line  from teste
unpivot ( dado for coluna in (c1,c2,c3,c4))
order by line, dado)
group by line;
Resultado:

Selecionar tudo

LINE DADO_ORDEM
---- ------------------
a    1 - 2 - 3 - 4
b    1 - 2 - 3 - 4
c    1 - 6 - 7 - 8
Explicando:

O Unpivot vai gerar em linhas os dados das colunas e colocá-las em ordem, e o listagg volta para o resultado ordenado em uma linha separado por ' - ' ou se deixar em branco...

Como eu fiz o exemplo baseado nos dados que você passou, pode ser que tenha que adaptar para a sua realidade...

Boa sorte!

[]s Ishii
:-o :-o :-o :-o
gfkauer
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 389
Registrado em: Ter, 27 Jul 2010 1:34 pm
Localização: Sapiranga - RS
Contato:
Quem falou que programar era fácil??

Quanto mais dificil for a implementação mais valorizado seu trabalho será!

Acessem: www.gfkauer.com.br

Que coisa linda!!!!
Desconhecia este comando...

Parabens pelo código...
ishii
Rank: Analista Júnior
Rank: Analista Júnior
Mensagens: 82
Registrado em: Ter, 28 Dez 2010 7:41 pm
Localização: São Paulo - SP

Olá,

São as novas features do Oracle 11gR2 tem uns artigos escritos pelo Arup Nanda (GUOB Tech Day 2011) que explicam muitas coisas. Leitura obrigatória!!!!

http://www.oracle.com/technetwork/artic ... 99021.html

E especificamente sobre o PIVOT e UNPIVOT

http://www.oracle.com/technetwork/artic ... 97235.html

[]s Ishii
:-o
Avatar do usuário
stcoutinho
Moderador
Moderador
Mensagens: 850
Registrado em: Qua, 11 Mai 2011 5:15 pm
Localização: são Paulo - SP

Puxa iishi,

Muito legal os exemplos que você costuma postar no forum.

Eu estava neste momento tentando resolver este problema com o uso de collections:

http://www.andrels.com/wp-pt_BR/index.p ... ollection/
http://www.orafaq.com/forum/t/67503/2/

Mas com o seu exemplo fica bem mais simples.

Abraços,

Sergio
rogenaro
Rank: DBA Pleno
Rank: DBA Pleno
Mensagens: 232
Registrado em: Sex, 30 Mar 2007 7:26 pm
Localização: Londrina - PR
Rafael O. Genaro

Na versão 10 também seria possível usar o connect_by_path (aproveitando as tabelas criadas pelo ishii):

Selecionar tudo

select line
     , substr( max( sys_connect_by_path(c, ' - ') ), 4 )
from 
(
  select line
       , c
       , row_number() over ( partition by line order by c asc ) rn
  from
  (
    select line
         , lvl
         , max( decode( lvl
                      , 1, c1
                      , 2, c2 
                      , 3, c3
                      , 4, c4
                      ) 
              ) c
    from   teste t
         , ( select level lvl from dual connect by level <= 4 ) /* ou qualquer outra forma de gerar uma linha para cada coluna que será transposta */
    group by line, lvl
  )
) a
connect by rn   = prior rn + 1 
and        line = prior line
start with rn = 1
group by line
ishii
Rank: Analista Júnior
Rank: Analista Júnior
Mensagens: 82
Registrado em: Ter, 28 Dez 2010 7:41 pm
Localização: São Paulo - SP

Olá,

Perfeito! Falta só o order by line no final para que funcione sempre!

[]s Ishii

"Escreva quanto código você precisar, mas sempre o mínimo possível!" - Tom Kyte
Avatar do usuário
dr_gori
Moderador
Moderador
Mensagens: 5024
Registrado em: Seg, 03 Mai 2004 3:08 pm
Localização: Portland, OR USA
Contato:
Thomas F. G

Você já respondeu a dúvida de alguém hoje?
https://glufke.net/oracle/search.php?search_id=unanswered

MUITO BOM ! :-D
numerus
Rank: Analista Júnior
Rank: Analista Júnior
Mensagens: 71
Registrado em: Seg, 23 Mai 2011 11:56 am
Localização: SP

Galera SENSACIONAL, não respondi antes por estar viajando.... cheguei agora e viajei novamente nos codigos perfeito de vocês parabens, não sei o que faria sem ajuda de vocês, abraços a todos, voces são demais.
Responder
  • Informação