Query

13 respostas
ftrapnell

Galera,

estou precisando de um help para montar uma query…

Tenho a seguinte situação, uma tabela com uma PK formada por duas colunas, ID e INDEX, por que preciso guardar histórico mensal(INDEX)
de alterações para cada objeto (identificado por ID);

Portanto a tabela está assim…

ID INDEX NAME

ID1 IDX1 Obj1
ID1 IDX2 Obj1
ID2 IDX1 Obj2
ID2 IDX2 Obj2
ID3 IDX1 Obj3
ID4 IDX1 Obj4
ID5 IDX1 Obj5
ID5 IDX2 Obj5
ID5 IDX3 Obj5
ID6 IDX1 Obj6

Eu preciso fazer uma query que me retorne todos os objetos, porém os que possuem mais de um índice,
devem retornar apenas o registro com o maior índice…

A consulta deve retornar assim:

ID INDEX NAME

ID1 IDX2 Obj1
ID2 IDX2 Obj2
ID3 IDX1 Obj3
ID4 IDX1 Obj4
ID5 IDX3 Obj5
ID6 IDX1 Obj6

Alguém pode me ajudar com esta query? Estou trabalhando com Oracle XE 10g…

Valeu…

[]´s

13 Respostas

rafaelglauber

Oi,

tá meio confuso essa sua pergunta…mas veja se é isso que você quer:

select ID, MAX(INDEX), COUNT(*) -- só para você conferir quantos registros com o mesmo ID from tabela group by ID having count(*)>1

rodrigoallemand

Vc está usando alguma engine de persistencia, como o Hibernate ou o JPA ou vai resolver isso ai na unha?
Antes de qq coisa, pra não perder perfoemance na consulta, deve-se criar indices para resolver esse lance dos IDs, deixando os dois na arvore… Eu faria uma view pra isso…

ftrapnell

rafaelglauber,

é confuso mesmo… eu tmb tô me enrolando aqui…
A sua query retornou somente os registros com o maior INDEX…

ID INDEX NAME

ID5 IDX3 Obj5

o que preciso são todos os objetos, com o valor de maior INDEX de cada ID

ID INDEX NAME

ID1 IDX2 Obj1
ID2 IDX2 Obj2
ID3 IDX1 Obj3
ID4 IDX1 Obj4
ID5 IDX3 Obj5
ID6 IDX1 Obj6

lembrando que o select * from tabela; retorna:
ID INDEX NAME

ID1 IDX1 Obj1
ID1 IDX2 Obj1
ID2 IDX1 Obj2
ID2 IDX2 Obj2
ID3 IDX1 Obj3
ID4 IDX1 Obj4
ID5 IDX1 Obj5
ID5 IDX2 Obj5
ID5 IDX3 Obj5
ID6 IDX1 Obj6

valeu…

rafaelglauber

Oi,

Ai é simples, é um group by simples:

select ID, MAX(INDEX) from tabela group by ID

ftrapnell

rodrigoallemand,

Estou fazendo na unha mesmo, pq estou programando dentro de uma ferramenta proprietária, usando linguagem JavaScript, consegui apenas uma conexão JDBC simples com o BD…

O indice que tem lá no Banco é o de PK, com as duas colunas…
CREATE UNIQUE INDEX “PK_TABELA” ON “TABELA” (“ID”, “INDEX”)
Foi isso que vc quis dizer??

Eu tmb pensei em view, mais não manjo muito…
Pode exemplificar melhor?

valeu pela ajuda…

ftrapnell

Boooa rafaelglauber,

é exatamente isso, e agora como retornar todas as colunas sem estragar a query??

tem que colocar todas no select e também no group by??

obrigado pela ajuda…

[]´s

rafaelglauber

Veja bem…quando você tá agrupando dados você tem que ter critério para isso, os outros dados você quer que venham como? O maior, o menor, a soma…quando você adiciona algo na clausula group by o resultado pode mudar…detalhe mais ai…por exemplo, se você quiser a terceira coluna como a maior, não precisa alterar muito, basta:

select
  ID,
  MAX(INDEX),
  MAX(NAME)
from tabela
group by
  ID

EDIT: nada de conseguir ajeitar as tags nesta mensagem… :cry:

ftrapnell

é, na verdade a tabela tem uma série de outras colunas, como:
ACTUALVALUE, PLANVALUE, MAXVALUE, MINVALUE e etc…

poranto eu precisava retornar a query, com os registros exatamente como retornamos com o Group by, porém estas outras colunas com os valores normais… sem alteração…

por exemplo, eu preciso da quarta coluna, mais não o maior, e sim com o valor do último registro tipo:

ID INDEX NAME ACTUALVALUE

ID1 IDX2 Obj1 12
ID2 IDX2 Obj2 15
ID3 IDX1 Obj3 21
ID4 IDX1 Obj4 34
ID5 IDX3 Obj5 23
ID6 IDX1 Obj6 43

onde um select * retornaria:
ID INDEX NAME ACTUALVALUE

ID1 IDX1 Obj1 10
ID1 IDX2 Obj1 12 <=(registro que preciso)
ID2 IDX1 Obj2 13
ID2 IDX2 Obj2 15 <=(registro que preciso)
ID3 IDX1 Obj3 21 <=(registro que preciso)
ID4 IDX1 Obj4 34 <=(registro que preciso)
ID5 IDX1 Obj5 21
ID5 IDX2 Obj5 22
ID5 IDX3 Obj5 23 <=(registro que preciso)
ID6 IDX1 Obj6 43 <=(registro que preciso)

entende? não quero somar mais nada, nem alterar valor de nenhuma coluna… tipo um select * porém selecionando somente os registros que retornaram no select com o group by que vc fez…

[]´s

rafaelglauber

No exemplo que você colocou acima reparei que o último valor é sempre o maior valor, certo? Se for assim bastaria:

select ID, MAX(INDEX), MAX(NAME), MAX(ACTUALVALUE) -- e assim sucessivamente...um monte de MAX from tabela group by ID

ftrapnell

É o maior valor, no exemplo… (foi mal)
mais nem sempre vai ser o maior valor daquela coluna, deve ser o valor onde o registro é o maior INDEX…

e deve retornar todas as colunas da tabela…

poderia ser:

onde um select * retornaria:
ID INDEX NAME ACTUALVALUE

ID1 IDX1 Obj1 10
ID1 IDX2 Obj1 12 <=(registro que preciso)
ID2 IDX1 Obj2 13
ID2 IDX2 Obj2 15 <=(registro que preciso)
ID3 IDX1 Obj3 21 <=(registro que preciso)
ID4 IDX1 Obj4 34 <=(registro que preciso)
ID5 IDX1 Obj5 300
ID5 IDX2 Obj5 200
ID5 IDX3 Obj5 23 <=(registro que preciso)
ID6 IDX1 Obj6 43 <=(registro que preciso)

mais também deve retornar todas as colunas, seguindo a mesma regra desta coluna ACTUALVALUE…

Eu estou pensando em um union… sei lá… talvez o Group by não seja a melhor solução…

o que vc´s acham???

[]´s

rafaelglauber

Oi,

Tá abusando né?
select
  ID,
  max(INDEX) as INDEX,
  (select NAME from tabela b 
   where b.ID = a.ID
     and b.INDEX = (select max(INDEX) 
                    from tabela c 
                    where c.ID = a.ID) ) as NAME,

  (select ACTUALVALUE from tabela b 
   where b.ID = a.ID
     and b.INDEX = (select max(INDEX) 
                    from tabela c 
                    where c.ID = a.ID) ) as ACTUALVALUE

from tabela a
group by ID

adapta cada subquery para a coluna que você quer.

ftrapnell

hahaha… valeu parceiro… obrigado pela ajuda…

vou testar desta forma…

ftrapnell

É isso aí parceiro… exatamente o que eu preciso… vai ficar grande mais pelo menos tá certo…

Muito obrigado pela força…

[]´s

Criado 18 de setembro de 2008
Ultima resposta 18 de set. de 2008
Respostas 13
Participantes 3