none
Inner Join em tabela n - n

    Question

  • Olá pessoal, estou denovo com um problema parecido.

    Tabelas:
    usuario - dados dos usuarios,
    tipo_usuario - tipos de usuarios,
    usuario_tipo_usuario - atribui os tipos aos usuarios (tabela com ligação n - n  entre usuario e tipo_usuario) e
    unidade.

    Um usuário pode ter mais de um tipo, e pode ter um tipo repetido caso for em outra unidade.

    Ex: um usuario pode ter 3 permissoes de coordenador de curso caso cada uma seja em uma unidade.

    entao eu quero nesta consulta listar os usuarios e seus tipo passando os ids das unidades.

    A tabela usuario_tipo_usuario possui esse id. Porém como nesta tabela há uma repetição grande de usuarios, o inner join retorna dados repetidos.
    Ex
    id    id_usuario    id_unidade    id_tipo_usuario
    433    122    1    3
    434    122    1    1
    435    122    2    2
    436    126    2    2
    437    122    2    4
    438    122    3    3
    440    123    1    1
    441    123    2    2
    442    123    1    1
    443    123    1    3
    444    126    1    4
    445    123    1    4
    446    123    1    1
    448    124    1    2
    449    125    1    2
    450    124    1    1
    452    125    1    2
    454    126    1    2
    455    126    2    3
    456    125    1    4
    457    125    1    1
    458    125    1    4
    459    125    1    4
    460    126    3    3
    461    126    4    3
    462    126    1    3
    463    126    8    3
    465    127    1    1
    466    127    1    2
    467    127    1    4
    468    127    2    1
    469    127    3    1

    Como no exemplo acima, usuario com 3 tipos de usuarios, na consulta é retornado 3 vezes o mesmo usuario.


    a Consulta:
    select u.login, u.id, uu.id_unidade as unidade, u.user_id, u.bairro, u.cep, u.cidade,
    u.complemento, u.cpf, rtrim(convert(char,u.data_nasc,103)) as data_nasc, u.email, u.estado, u.nome,
    u.sobrenome, u.nome_logradouro, u.nome_mae, u.nome_pai, u.numero_residencia, u.rg, u.sexo, u.tel_cel,
    u.tel_cel2, u.tel_comer, u.tel_comer_ramal, u.tel_fax, u.tel_resid, u.tel_resid2, u.tipo_logradouro,
    (u.nome + ' ' + u.sobrenome) as nomeCompleto
    from usuario u
    inner join usuario_tipo_usuario uu
    on (uu.id_usuario = u.id) and (uu.id_unidade = 1 or uu.id_unidade = 2 or uu.id_unidade = 3)
    where u.removido = 0

    o retorno dela (diminui a quantidade de campos do retorno para melhro visualização):

    o campos id é referente ao id do usuario como chave estrangeira na tabela com ligação n - n

    id       login    unidade
    122    jujuca    1
    122    jujuca    1
    122    jujuca    2
    126    bacana    2
    122    jujuca    2
    122    jujuca    3
    123    jeba    1
    123    jeba    2
    123    jeba    1
    123    jeba    1
    126    bacana    1
    123    jeba    1
    123    jeba    1
    124    bobo    1
    125    novo2    1
    124    bobo    1
    125    novo2    1
    126    bacana    1
    126    bacana    2
    125    novo2    1
    125    novo2    1
    125    novo2    1
    125    novo2    1
    126    bacana    3
    126    bacana    1
    127    zangado    1
    127    zangado    1
    127    zangado    1
    127    zangado    2
    127    zangado    3


    Alguem tem alguma ideia de como fazer isso?
    Tuesday, February 23, 2010 1:14 PM

Answers

  • Então João, no caso não teria como fazer o que você quer pelo seguinte propósito.
    Você tem varios usuários com diferentes registros. O Inner join pega tudo que é igual e traz para você na sua consulta.

    Por exemplo:

    ID USAURIO USUARIO_TIPO
    1 Joaozinho Gerente
    1 Joaozinho Supervisor
    2 Juares Gerente
    3 Betao Operario
    3 Betao Maquinario


    Mesmo você colocando um group by na sua consulta ele vai trazer 2x o joaozinho, por que ele tem um campo que diz que ele é gerente e ao mesmo tempo supervisor. (Essa tabela é apenas um exemplo ok, não que seja usado no seu exemplo).

    Agora se você quiser que mesmo assim traga os apenas 1 usuário para cada situação, você tem que tirar todas os campos que tem informações diferentes. Ou seja, na tabela acima, teria que tirar o campo USUARIO_TIPO, ai sim ele ia trazer a tabela como mostra abaixo.

    ID USAURIO
    1 Joaozinho
    2 Juares
    3 Betao


    Abraço

    Clayton Santos
    • Marked as answer by João Fontana Tuesday, February 23, 2010 5:36 PM
    Tuesday, February 23, 2010 4:21 PM

All replies

  • Você jé tentou com GROUP BY?

    http://www.java2s.com/Code/SQLServer/Select-Query/Group-BY.htm
    Américo Arvani MCP/MCTS - WEB Se ajudou , marque como resposta.
    Tuesday, February 23, 2010 2:15 PM
  • Tentei, mas não consegui pensar em uma condição having para mostrar apenas um registro de cada usuário.
    Tuesday, February 23, 2010 2:21 PM
  • Olâ João, Como vai?

    Cara, sua explicação não está um pouco confusa. Você precisa retornar os usuarios de todas as unidades, e o problema é que está duplicando os usuarios é isso?

    Abraço

    Clayton Santos

    Tuesday, February 23, 2010 2:51 PM
  • No Select utilize a clausula MAX(u.id) ou MIN() nos dados que você não quer repetir.
    Américo Arvani MCP/MCTS - WEB Se ajudou , marque como resposta.
    Tuesday, February 23, 2010 2:54 PM
  • isso, seria isso mesmo, quero que retorne os usuarios das unidades, mas não repetir eles para cada registro.

    gostaria de apenas um registro para cada usuário, pois na tabela que eu faço inner join existem varios registros do mesmo usuario em unidades diferentes.
    Tuesday, February 23, 2010 2:57 PM
  • Então João, no caso não teria como fazer o que você quer pelo seguinte propósito.
    Você tem varios usuários com diferentes registros. O Inner join pega tudo que é igual e traz para você na sua consulta.

    Por exemplo:

    ID USAURIO USUARIO_TIPO
    1 Joaozinho Gerente
    1 Joaozinho Supervisor
    2 Juares Gerente
    3 Betao Operario
    3 Betao Maquinario


    Mesmo você colocando um group by na sua consulta ele vai trazer 2x o joaozinho, por que ele tem um campo que diz que ele é gerente e ao mesmo tempo supervisor. (Essa tabela é apenas um exemplo ok, não que seja usado no seu exemplo).

    Agora se você quiser que mesmo assim traga os apenas 1 usuário para cada situação, você tem que tirar todas os campos que tem informações diferentes. Ou seja, na tabela acima, teria que tirar o campo USUARIO_TIPO, ai sim ele ia trazer a tabela como mostra abaixo.

    ID USAURIO
    1 Joaozinho
    2 Juares
    3 Betao


    Abraço

    Clayton Santos
    • Marked as answer by João Fontana Tuesday, February 23, 2010 5:36 PM
    Tuesday, February 23, 2010 4:21 PM

  • Blz Clayton, deu certo agora cara. Era isso mesmo.

    Vlwww.
    Tuesday, February 23, 2010 5:37 PM
  • Flws... Se precisar de ajuda manda ai!

    Sempre quando você fizer uma query e ela duplicar o registro, tenha certeza que tem um campo onde ele está duplicado, e por esse motivo ela duplica mostrando os dois registros ok.

    Abraço

    Clayton Santos

    Tuesday, February 23, 2010 5:44 PM