Eduardo, Muito obrigado pela sua ajuda. Conforme as evidências, no visual estava assim. Não existia diferença. Até fiz alguns testes rodando a query direto no sqlplus, no pl/sql developer pensando nisso, mas passou despercebido que poderia ser isso.
id per. valor_1 valor_2 code dense_rank ---- ----- --------------------------- -------------------------- -------- ----------------- 7 1 16262927843,1253 1303006,45802409 0688 1 18 1 16262927843,1153 1303006,45802409 0691 2 15 1 16262927843,1153 1303006,45802409 0447 3 Fiz novamente update nas colunas em todos os id´s envolvidos, atribuindo o mesmo conteudo em valor_1 e valor_2 e funcionou. id per. valor_1 valor_2 code dense_rank ---- ----- --------------------------- -------------------------- -------- ----------------- 19 1 16262927843,11529920 1303006,45802409 0348 1 15 1 16262927843,11529920 1303006,45802409 0447 2 7 1 16262927843,11529920 1303006,45802409 0688 3 18 1 16262927843,11529920 1303006,45802409 0691 4 13 1 3744493176,06001997 300054,66430277 0450 5 0348 é o menor code e veio como DENSE_RANK = 1. Problema resolvido. Conclusão: Os valores que a ferramenta estava mostrando, possivelmente formatado, estava diferente do que estava gravado. Obrigado mesmo pela atenção dispensada. []s Eriovaldo 2009/4/24 Claro, Eduardo <eduardo.cl...@eds.com> > > > Eriovaldo, > > Será que os valores não estão apenas "aparentando" ser iguais, por causa da > formatação das colunas por exemplo, mas na verdade são diferentes? > > Por exemplo, imagine que na tabela os valor1 das linhas 2 e 3 na verdade > sejam 16262927843.11533 e 16262927843.11531 , mas como está formatado para 4 > casas decimais aparecem iguais, e trazendo a confusão. > > Dá uma olhada nos valores internos, sem nenhuma formatação, pra confirmar > isso. > > Por exemplo, se eu pegar a sua query de exemplo e implementar esta > diferença que não aparece por causa da formatação, consigo reproduzir a > confusão de que estou falando. Veja: > > SQL> col valor2 for 9999.99999 > > SQL> select id, periodo, valor_1, valor_2, codigo, > > 2 DENSE_RANK() > > 3 OVER (PARTITION BY periodo > > 4 ORDER BY valor_1 desc , > > 5 valor_2 desc , > > 6 codigo asc) AS DENSE_RANK > > 7 from (select id, > > 8 periodo, > > 9 sum(num1) valor_1, > > 10 sum(num2) valor_2, > > 11 codigo > > 12 from(select 1 id, 1 periodo, 100.34 as num1, 200.4545452 as num2, '0691' > as > > 13 codigo from dual > > 14 union all > > 15 select 2 id, 1 periodo, 100.34 as num1, 200.4545451 as num2, '0447' as > > 16 codigo from dual > > 17 union all > > 18 select 3 id, 1 periodo, 30 as num1, 1200 as num2, '0999' as codigo > > 19 from dual > > 20 union all > > 21 select 4 id, 1 periodo, 30 as num1, 1200 as num2, '0001' as codigo > > 22 from dual > > 23 union all > > 24 select 5 id, 1 periodo, 33 as num1, 1200 as num2, '0999' as codigo > > 25 from dual > > 26 union all > > 27 select 6 id, 1 periodo, 30 as num1, 1200 as num2, '0888' as codigo > > 28 from dual) > > 29 group by id, periodo, codigo); > > ID PERIODO VALOR_1 VALOR_2 CODI DENSE_RANK > > --------- --------- --------- --------- ---- ---------- > > 1 1 100.34 200.45455 0691 1 > > 2 1 100.34 200.45455 0447 2 > > 5 1 33 1200 0999 3 > > 4 1 30 1200 0001 4 > > 6 1 30 1200 0888 5 > > 3 1 30 1200 0999 6 > > 6 rows selected. > > Veja que os valores agora são diferentes na sexta casa decimal para a > coluna valor2. Mas, como eu formatei para mostrar apenas cinco casas > decimais, eles aparecem iguais e o resultado parece mostrar que o DENSE_RANK > não está funcionando. > > []s > > -- > > Eduardo Claro > > From: oracle_br@yahoogrupos.com.br <oracle_br%40yahoogrupos.com.br>[mailto: > oracle_br@yahoogrupos.com.br <oracle_br%40yahoogrupos.com.br>] On Behalf > Of Eriovaldo Andrietta > Sent: quinta-feira, 23 de abril de 2009 23:00 > To: oracle_br@yahoogrupos.com.br <oracle_br%40yahoogrupos.com.br> > Subject: Re: [oracle_br] Dúvida sobre Order by > > Eduardo e colegas, > > Eduardo: Grato pela dica do ASCII. aprendi mais uma. > > Desculpem-me pelo e-mail extenso, mas segue aqui o relato em detalhes do > problema que estou enfrentando. A solução deve ser simples, apesar do > e-mail > extenso. > > Observações: > > a.) tentei fazer o ORDER BY sem usar o DENSE_RANK e o resultado é o mesmo, > não funcionou na query original postada abaixo. Estranho que na simulação > funcionou. > > b.) Parece que o ORDER BY (desc , asc) não está sendo usado corretamente, > por isso estou postando o problema, que certamente será lessons learn para > o > grupo. > > c.) Versão do oracle : Oracle 10g. > Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Prod > PL/SQL Release 10.2.0.4.0 - Production > CORE 10.2.0.4.0 Production > TNS for 32-bit Windows: Version 10.2.0.4.0 - Production > NLSRTL Version 10.2.0.4.0 - Production > > d.) gostaria de resolver isso somente com SQL, sem ter que fazer código em > PL/SQL. > > Objetivo: > > Obter uma lista de valores com classificação pelo maior valor. > > Regra do Negócio: > > O maior VALOR_1 será o campeão e o DENSE_RANK dele deve ser 1. > Se empatar no VALOR_1, analisar o maior VALOR_2. > Se ainda assim empatar, o critério de desempate é o menor CODE. > > 1.) Query montada para simular usando o DENSE_RANK. (AQUI FUNCIONOU) > > select id, periodo, valor_1, valor_2, codigo, > DENSE_RANK() > OVER (PARTITION BY periodo > ORDER BY valor_1 desc , > valor_2 desc , > codigo asc) AS DENSE_RANK > from (select id, > periodo, > sum(num1) valor_1, > sum(num2) valor_2, > codigo > from(select 1 id, 1 periodo, 100.34 as num1, 200.454545 as num2, '0691' as > codigo from dual > union all > select 2 id, 1 periodo, 100.34 as num1, 200.454545 as num2, '0447' as > codigo from dual > union all > select 3 id, 1 periodo, 30 as num1, 1200 as num2, '0999' as codigo > from dual > union all > select 4 id, 1 periodo, 30 as num1, 1200 as num2, '0001' as codigo > from dual > union all > select 5 id, 1 periodo, 33 as num1, 1200 as num2, '0999' as codigo > from dual > union all > select 6 id, 1 periodo, 30 as num1, 1200 as num2, '0888' as codigo > from dual) > group by id, periodo, codigo) > > Resultado: > id per. valor_1 valor_2 > code dense_rank > ---- ----- --------------------------- > -------------------------- -------- ----------------- > 2 1 100,34 200,454545 0447 > 1 > 1 1 100,34 200,454545 0691 > 2 > 5 1 33 1200 > 0999 3 > 4 1 30 1200 > 0001 4 > 6 1 30 1200 > 0888 5 > 3 1 30 1200 > 0999 6 > > Conclusão: > > O valor 100,34 empatou nas 2 primeiras linhas, > O valor 200,454545 empatou nas 2 primeiras linhas > Preciso que o menor código desempate o ranking. > No caso simulado fez corretamente, pois o 0447 é o menor código das linhas > empatadas e veio com DENSE_RANK = 1. > > 2.) Query original (AQUI NÃO FUNCIONA). > > Datatypes relevantes: A coluna attribute_value é um NUMBER(38,8) > e a coluna CODE é um VARCHAR2(4). > > A query abaixo, fiz tambem, sem SUM, trazendo os valores direto em 1 > linha só, colocando duas vezes a tabela entidade_summary e o problema > persiste. > > SELECT id, periodo, valor_1, valor_2, code, > DENSE_RANK() > OVER (PARTITION BY periodo > ORDER BY valor_1 desc, > valor_2 desc, > code asc) AS DENSE_RANK > FROM (SELECT parent_id id, > si_period_id periodo, > sum(valor_1) valor_1, > sum(valor_2) valor_2, > code > FROM(SELECT d.parent_id, > d.si_period_id, > d.attribute_value valor_1, > null valor_2, > entidade.code > FROM entidade_summary d > , entidade > WHERE d.attribute_code = 'VALOR_1' > AND d.si_period_id = 1 > AND d.attribute_value IS NOT NULL > AND d.reference_year IS NULL > AND d.parent_id = entidade.id > UNION ALL > SELECT d.parent_id, > d.si_period_id, > null valor_1, > d.attribute_value valor_2, > entidade.code > FROM entidade_summary d > , entidade > WHERE d.attribute_code = 'VALOR_2' > AND d.si_period_id = 1 > AND d.attribute_value IS NOT NULL > AND d.reference_year IS NULL > AND d.parent_id = entidade.id > ) > GROUP BY parent_id, > si_period_id, > code > ) > > Resultado gerado pela query original > : > id per. valor_1 valor_2 > code dense_rank > ---- ----- --------------------------- > -------------------------- -------- ----------------- > 7 1 16262927843,1253 1303006,45802409 0688 1 > 18 1 16262927843,1153 1303006,45802409 0691 2 > 15 1 16262927843,1153 1303006,45802409 0447 3 > 1 1 16262927843,1153 1303006,45802409 0687 4 > 19 1 3930077927,06403 314894,446515 0348 5 > > Análise: > > O valor 16262927843,1253 é o campeão, está com DENSE_RANK = 1. Isto está > correto. > O valor 16262927843,1153 aparece na segunda e terceira linha. Então > empatou. > O segundo critério é avaliar VALOR_2. que também empatou na primeira e > segunda linha. > O critério final de desempate é classificar pelo menor CODE. > Como o código 0447 é menor, é esperado que ele apareça no DENSE_RANK = 2 e > não 3. > > O que parece não estar funcionando é essa parte da query: > > ORDER BY valor_1 desc, > valor_2 desc, > code asc) AS DENSE_RANK > > Parece que não está fazendo a ordenação ascendente pela coluna CODE. > > Pois, empatou em VALOR_1, empatou em VALOR_2 e o desempate seria pelo menor > código, > no entanto isso não está acontecendo, pois o CODE 0447 veio como 3 e não > como 2. > > Resultado pretendido: > > id per. valor_1 valor_2 > code dense_rank > ---- ----- --------------------------- > -------------------------- -------- ----------------- > 3 15 1 16262927843,1153 1303006,45802409 0447 2 > 2 18 1 16262927843,1153 1303006,45802409 0691 3 > > Se alguém souber o motivo pelo qual o DESC, DESC, ASC não acontece, ficarei > grato. > > Grato > Eriovaldo > > 2009/4/23 Claro, Eduardo <eduardo.cl...@eds.com > <eduardo.claro%40eds.com><mailto: > eduardo.claro%40eds.com <eduardo.claro%2540eds.com>> > > > > > > > > Gleyson, > > > > A função ASCII retorna o código ASCII do primeiro caractere da sua > string. > > Portanto, ASCII('0691') e ASCII('0447') na verdade serão executados como > > simplesmente ASCII('0'), e por isso o resultado é igual. > > > > Quanto à sua query, por favor poste um exemplo completo, que possa ser > > executado e verificado, para facilitar. > > > > Seu exemplo pode por exemplo ser do tipo que você usou no início da sua > > explicação, com dois SELECTs FROM DUAL, mas já usando o DENSE RANK e > > reproduzindo o problema, ok? > > > > -- > > > > Eduardo Claro > > > > From: oracle_br@yahoogrupos.com.br <oracle_br%40yahoogrupos.com.br><mailto: > oracle_br%40yahoogrupos.com.br <oracle_br%2540yahoogrupos.com.br>> > <oracle_br%40yahoogrupos.com.br>[mailto: > > oracle_br@yahoogrupos.com.br <oracle_br%40yahoogrupos.com.br> <mailto: > oracle_br%40yahoogrupos.com.br <oracle_br%2540yahoogrupos.com.br>> > <oracle_br%40yahoogrupos.com.br>] On Behalf > > Of Eriovaldo Andrietta > > Sent: quinta-feira, 23 de abril de 2009 11:27 > > To: oracle_br@yahoogrupos.com.br <oracle_br%40yahoogrupos.com.br><mailto: > oracle_br%40yahoogrupos.com.br <oracle_br%2540yahoogrupos.com.br>> > <oracle_br%40yahoogrupos.com.br> > > > Subject: Re: [oracle_br] Dúvida sobre Order by > > > > > > Gleyson, > > > > 1.) Eu já tenho um outro order by, que é usado depois que consigo o > > DENSE_RANK. > > O meu problema é o order by que gera o DENSE_RANK, pois espero que a > coluna > > alfanumérica seja classificada de forma ascendente para trazer o código > > 0447 com DENSE_RANK = 1 e não igual a 2. Estou entendendo que o > DENSE_RANK > > é > > o rownum do resultado. > > > > 2.) Estou tentando fazer um order by direto na query sem DENSE_RANK e > > também não está funcionando. > > > > ORDER BY d.si_period_id asc, -- 01 > > d.attribute_value desc, -- 02 > > e.attribute_value desc, -- 03 > > entidade.code asc -- 04 > > 1 2 3 4 > > dense > > 1 16262927843,11529920 1303006,45802409 0691 1 18 > > 1 16262927843,11529920 1303006,45802409 0447 2 15 > > 1 3930077927,06403017 314894,44651500 0348 3 19 > > 1 3744493176,06001997 300054,66430277 0450 4 13 > > > > Preciso que o dense da segunda linha seja 1 e o dense da primeira seja 2 > > que é a classificação ascendente da quarta coluna, o código menor > primeiro. > > > > 3.) Curioso: > > > > se eu fizer : > > > > SQL> select ascii('0691') from dual; > > > > ASCII('0691') > > ------------- > > 48 > > SQL> select ascii('0447') from dual; > > > > ASCII('0447') > > ------------- > > 48 > > > > Será que o order by está usando isso para classificar ? > > > > Grato pela ajuda. > > > > 2009/4/23 Gleyson Melo <gleysonm...@gmail.com > > <gleysonmelo%40gmail.com><mailto: > gleysonmelo%40gmail.com <gleysonmelo%2540gmail.com>> <gleysonmelo% > 40gmail.com><mailto: > > gleysonmelo%40gmail.com <gleysonmelo%2540gmail.com>> > > > > > > > > > > > > Fala Eriovaldo! > > > Cara, aquele ORDER BY foi apenas pra gerar o valor final do RANK. Pra > > gerar > > > a saída que tu queres, tens que colocar o ORDER BY no final da consulta > > > também. > > > > > > 2009/4/22 Eriovaldo Andrietta > > > <ecandrie...@gmail.com<ecandrietta%40gmail.com><mailto: > ecandrietta%40gmail.com <ecandrietta%2540gmail.com>> <ecandrietta% > 40gmail.com><mailto: > > ecandrietta%40gmail.com <ecandrietta%2540gmail.com>> <ecandrietta% > > > 40gmail.com>> > > > > > > > > > > > > > > > > > > > > > > > Olá pessoal, > > > > > > > > Veja se alguém pode me ajudar: > > > > > > > > Quando faço esta query ordenando a coluna text de forma desc tenho > 0447 > > > no > > > > final: > > > > select 100 as num1, 200 as num2, > > > > '0691' as text from dual > > > > union all > > > > select 100 as num1, 200 as num2, > > > > '0447' as text from dual > > > > order by 1 desc, 2 desc, 3 desc > > > > > > > > 1 100 200 0691 > > > > 2 100 200 0447 > > > > > > > > Quando faço esta query ordenando a coluna text de forma asc tenho > 0447 > > no > > > > começo: > > > > > > > > select 100 as num1, 200 as num2, > > > > '0691' as text from dual > > > > union all > > > > select 100 as num1, 200 as num2, > > > > '0447' as text from dual > > > > order by 1 desc, 2 desc, 3 asc > > > > > > > > 1 100 200 0447 > > > > 2 100 200 0691 > > > > > > > > até ai tudo bem. é isso mesmo que eu quero, O desc desc asc funciona, > > > > porém: > > > > > > > > quando uso esse mesmo recurso em: > > > > > > > > DENSE_RANK() > > > > OVER (PARTITION BY d.si_period_id > > > > ORDER BY d.attribute_value desc , > > > > e.attribute_value desc , > > > > f.code asc) AS DENSE_RANK > > > > > > > > o 0447 sai sempre no final. > > > > > > > > Eu preciso do 0447 na primeira linha e a instrução não faz isso. > > > > > > > > Sai assim: > > > > > > > > 1 18 1 16262927843,11529920 1303006,45802409 0691 1 > > > > 2 15 1 16262927843,11529920 1303006,45802409 0447 2 > > > > > > > > E preciso do resultado assim, o menor código antes: > > > > > > > > 1 18 1 16262927843,11529920 1303006,45802409 0447 1 > > > > 2 15 1 16262927843,11529920 1303006,45802409 0691 2 > > > > > > > > O que tem de errado nisso ? > > > > > > > > Grato > > > > Eriovaldo > > > > > > > > [As partes desta mensagem que não continham texto foram removidas] > > > > > > > > > > > > > > > > > > -- > > > Atenciosamente, > > > Gleyson Melo > > > Oracle Database 10g Administrator Certified Professional > > > > > > [As partes desta mensagem que não continham texto foram removidas] > > > > > > > > > > > > > [As partes desta mensagem que não continham texto foram removidas] > > > > [As partes desta mensagem que não continham texto foram removidas] > > > > > > > > [As partes desta mensagem que não continham texto foram removidas] > > [As partes desta mensagem que não continham texto foram removidas] > > > [As partes desta mensagem que não continham texto foram removidas]