Listar titulares e dependentes

Dúvidas, dicas e truques de SQL, Select, Update, Delete, cláusulas, operações com joins, Funções em SQLs, etc
jks1903
Rank: DBA Júnior
Rank: DBA Júnior
Mensagens: 188
Registrado em: Qui, 04 Fev 2010 8:08 am

Pessoal, uma ajuda.
Preciso ordenar uma lista de usuários por titulares e dependentes, de forma que a lista seja classificada por nome de titular, porém com seus dependentes logo abaixo.
Não estou conseguindo montar uma lógica para classificar dessa forma.

A estrutura da tabela (com os campos que interessam aqui no momento) é assim:

Selecionar tudo

USUARIO
-------------
MATRICULA --matricula do usuario
NM_USUARIO --nome do usuario
TP_USUARIO --tipo do usuário. T para titular e D para dependente
MAT_TITULAR -- matricula do titular. Caso o usuário seja titular esse campo fica nulo.
Todos os usuários são cadastrados na mesma tabela.

Exemplo: se o usuário João da Silva tiver 3 dependentes, será apresentado o João, logo abaixo dele os 3 dependentes em ordem alfabética também e em seguida o próximo titular.


Obrigado.
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á,

Use o connect by prior...

[]s Ishii
jks1903
Rank: DBA Júnior
Rank: DBA Júnior
Mensagens: 188
Registrado em: Qui, 04 Fev 2010 8:08 am

beleza, estive pesquisando e acho que é por aí mesmo.
Porém eu não estou conseguindo montar essa query.
Estou tentando assim:

Selecionar tudo

select u.matricula, u.nm_usuario,  u.tp_usuario, u2.nm_usuario titular
from usuario u, usuario u2
connect by prior u.mat_titular = u2.matricula(+)
Porém, o processamento da query dura uma eternidade e cancelo. Na ultima vez cancelei com 5 minutos. Algo deve estar errado.

Também tentei inserir a cláusula no where, porém me retornou esse erro:

Selecionar tudo

ORA-01436: loop CONNECT BY nos dados do usuário

Poderia me mostrar um exemplo para esse caso?

Obrigado.
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

Olhando por cima, não creio que faltou um start with... (creio que seja este o comando).

Além de não ser nescessário o outer join.
jks1903
Rank: DBA Júnior
Rank: DBA Júnior
Mensagens: 188
Registrado em: Qui, 04 Fev 2010 8:08 am

Humm.

O start with é necessário sempre que eu utilizar CONNECT BY PRIOR?

Eu me baseei nesse exemplo:
http://download.oracle.com/docs/cd/B193 ... ies003.htm

O primeiro exemplo mostrado não utiliza o START WITH e exibe os dados exatamente como quero aqui.

E sobre o JOIN, se eu não utilizar dessa forma ele não irá trazer apenas os que possuem titular?

Obrigado.
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á,

Acho que a query é que não está adequada.

Tente assim:

Selecionar tudo

select decode (level, 1,'TITULAR','DEPENDENTE') ,lpad(' ',4 * level) || nm_usuario from usuario
start with tp_usuario = 'T'
connect by prior matricula = mat_titular
Só que para atender o que você precisa
Exemplo: se o usuário João da Silva tiver 3 dependentes, será apresentado o João, logo abaixo dele os 3 dependentes em ordem alfabética também e em seguida o próximo titular.
Acho que do Level 2 em diante não é possível colocar em ordem...

[]s Ishii
burga
Rank: DBA Pleno
Rank: DBA Pleno
Mensagens: 232
Registrado em: Qui, 26 Nov 2009 1:05 pm
Localização: SP
Ricardo H. Tajiri

Uma forma mais simples de solucionar seu problema é a seguinte:

Selecionar tudo

SELECT * FROM (
  SELECT MATRICULA, NM_USUARIO, TP_USUARIO, MATRICULA MAT_TITULAR 
  FROM USUARIO 
  WHERE TP_USUARIO = 'T'
  UNION ALL
  SELECT MATRICULA, NM_USUARIO, TP_USUARIO, MAT_TITULAR 
  FROM USUARIO 
  WHERE TP_USUARIO = 'D')
ORDER BY MAT_TITULAR, TP_USUARIO DESC, NM_USUARIO;
Isso funciona supondo que um dependente não possui outros dependentes e um titular também não possui outro titular.

Abraços,
jks1903
Rank: DBA Júnior
Rank: DBA Júnior
Mensagens: 188
Registrado em: Qui, 04 Fev 2010 8:08 am

Pessoal, vlw pelas respostas.

Achei a idéia do burga mais simples.
Apartir dela consegui montar a query.
Apenas substitui o campo matricula do titular pelo nome do titular, pois ali estava classificando por matrícula.

a query ficou assim:

Selecionar tudo

SELECT * FROM (
  SELECT MATRICULA, NM_USUARIO, TP_USUARIO, NM_USUARIO 
  FROM USUARIO
  WHERE TP_USUARIO = 'T'
  UNION ALL
  SELECT U.MATRICULA, U.NM_USUARIO, U.TP_USUARIO, U2.NM_USUARIO
  FROM USUARIO U, USUARIO U2
  WHERE U.TP_USUARIO = 'D' AND U.MAT_TITULAR = U2.MATRICULA)
ORDER BY 4, 3 DESC, 2;

Dessa forma funcionou perfeito.

Obrigado.
Responder
  • Informação
  • Quem está online

    Usuários navegando neste fórum: Nenhum usuário registrado e 15 visitantes