none
Select join em multi Tabelas RRS feed

  • Pergunta

  • Bom Dia

    estou tentando fazer um select na minha tabela de cliente e endereço de cliente porem não estou conseguindo fazer.

    tipo tenho 1 cliente que pode ter vários endereço porem no select quero que retorna-se apenas o primeiro endereço

    ex:

    nome    |  cidade

    Maria       São Luiz

    porem se o cliente tiver mais de um endereço e eu fazer um select ele retorna o nome do cliente repetido do tanto do endereço que ele tiver

    tentei usar um select dentro de um join mais a consulta ficou lenta.

    select nom_cli,
           cid_end
           from cliente as cli 
           join clienteend as endc on cli.cnpj_cpf_cli = endc.cnpj_cpf_end and cod_end = (select min(cod_end) from clienteend where cnpj_cpf_end = cli.cnpj_cpf_cli)

    alguém ai pode mi ajudar na montagem dessa query?

    der de já agradeço a atenção de todos

    segunda-feira, 24 de junho de 2019 15:01

Respostas

  • estou tentando fazer um select na minha tabela de cliente e endereço de cliente porem não estou conseguindo fazer.
    tipo tenho 1 cliente que pode ter vários endereço porem no select quero que retorna-se apenas o primeiro endereço

    Rhael, a coluna cod_end é a chave primária na tabela clienteend?

    Experimente usar subconsulta:

    -- código #1
    SELECT cli.nom_cli,
           (SELECT top (1) cid_end
              from clienteend as endc
              where endc.cnpj_cpf_end = cli.cnpj_cpf_cli
    order by endc.cod_end) as cid_end from cliente as cli;


    José Diz     Belo Horizonte, MG - Brasil     [T-SQL performance tuning: Porto SQL]   [e-mail]


    Este conteúdo é fornecido sem garantias de qualquer tipo, seja expressa ou implícita.

    • Editado José Diz terça-feira, 25 de junho de 2019 11:45
    • Sugerido como Resposta Junior Galvão - MVPMVP terça-feira, 25 de junho de 2019 12:17
    • Marcado como Resposta José Diz terça-feira, 2 de julho de 2019 15:36
    terça-feira, 25 de junho de 2019 11:31

Todas as Respostas

  • Rhael,

    Talvez o comando Top te ajude, veja se este exemplo:

    -- Criando a Tabela Clientes --
    Create Table Clientes
     (CodigoCliente Int Identity(1,1) Primary Key,
      NomeCliente Varchar(20) Not Null)
    Go
    
    -- Criando a Tabela ClientesEnderecos --
    Create Table ClientesEnderecos
     (CodigoEndereco Int Not Null Identity(1,1),
      CodigoCliente Int Not Null,
      Logradouro Varchar(100),
      CEP Int,
      Numero Int
      Constraint [PK_CodigoEndereco_CodigoCliente] Primary Key (CodigoEndereco, CodigoCliente))
    Go
    
    -- Inserindo Clientes --
    Insert Into Clientes (NomeCliente) 
    Values ('Pedro'),('Antonio'),('Galvão'),('Junior')
    Go
    
    -- Inserindo ClientesEnderecos --
    Insert Into ClientesEnderecos (CodigoCliente, Logradouro, CEP, Numero)
    Values (1,'Rua A',18133001,81),
                (1,'Rua B',18133002,181),
    		    (2,'Rua C',18133003,450),
    		    (2,'Rua D',18133004,20),
    		    (3,'Rua E',18133005,100)
    Go
    
    -- Código Similar ao seu ---
    Select C.NomeCliente,
               CE.Logradouro,
    		   CE.CEP,
    		   CE.Numero
    From Clientes C Inner Join ClientesEnderecos CE
                                                                   On C.CodigoCliente = CE.CodigoCliente
    															   And CE.CodigoEndereco = (Select MIN(CodigoEndereco) From ClientesEnderecos
    															                                               Where CodigoCliente = C.CodigoCliente)
    
    -- Usando Top Sem SubQuery --
    Select Top 1 C.NomeCliente,
               CE.Logradouro,
    	   CE.CEP,
    	   CE.Numero
    From Clientes C Inner Join ClientesEnderecos CE
                                                                   On C.CodigoCliente = CE.CodigoCliente
    Order By CE.CodigoEndereco Asc
    Go
    Ressalto que este é somente um esboço, uma ideia, não estou levando em consideração qualquer regra de negócio.


    Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]




    • Sugerido como Resposta IgorFKModerator segunda-feira, 24 de junho de 2019 19:58
    • Editado Junior Galvão - MVPMVP terça-feira, 25 de junho de 2019 12:36 Atualização no código de exemplo, removi a subquery.
    segunda-feira, 24 de junho de 2019 17:03
  • se eu usar

    (Select MIN(CodigoEndereco) From ClientesEnderecos Where CodigoCliente = C.CodigoCliente)

    a consulta ficar lenta já tentei usar dessa forma

    minha tabela de cliente tem uns 50 mil cliente se eu usar dessa forma fica muito lenta a consulta

    um amigo sugeriu eu usar um raw xml.

    mais não tenho ideia de como implementa isso.

    segunda-feira, 24 de junho de 2019 22:12
  • Boa noite,

    Experimente fazer uns testes utilizando o operador Apply:

    select 
        nom_cli,
        cid_end
    from cliente as cli 
    cross apply
    (
        select top(1)
            cid_end
        from clienteend as endc 
        where
            endc.cnpj_cpf_end = cli.cnpj_cpf_cli
        order by
            cod_end
    ) as ca
    

    Espero que ajude


    Assinatura: http://www.imoveisemexposicao.com.br

    segunda-feira, 24 de junho de 2019 23:06
  • estou tentando fazer um select na minha tabela de cliente e endereço de cliente porem não estou conseguindo fazer.
    tipo tenho 1 cliente que pode ter vários endereço porem no select quero que retorna-se apenas o primeiro endereço

    Rhael, a coluna cod_end é a chave primária na tabela clienteend?

    Experimente usar subconsulta:

    -- código #1
    SELECT cli.nom_cli,
           (SELECT top (1) cid_end
              from clienteend as endc
              where endc.cnpj_cpf_end = cli.cnpj_cpf_cli
    order by endc.cod_end) as cid_end from cliente as cli;


    José Diz     Belo Horizonte, MG - Brasil     [T-SQL performance tuning: Porto SQL]   [e-mail]


    Este conteúdo é fornecido sem garantias de qualquer tipo, seja expressa ou implícita.

    • Editado José Diz terça-feira, 25 de junho de 2019 11:45
    • Sugerido como Resposta Junior Galvão - MVPMVP terça-feira, 25 de junho de 2019 12:17
    • Marcado como Resposta José Diz terça-feira, 2 de julho de 2019 15:36
    terça-feira, 25 de junho de 2019 11:31
  • José Diz a consulta ficou mais rápida do que estava antes esta demorando 1:02 e passou a demora 0:16

    vc teria um outro abordagem pra melhora ainda mais essa buscar?

    der de já agradeço.

    terça-feira, 25 de junho de 2019 12:04
  • se eu usar

    (Select MIN(CodigoEndereco) From ClientesEnderecos Where CodigoCliente = C.CodigoCliente)

    a consulta ficar lenta já tentei usar dessa forma

    minha tabela de cliente tem uns 50 mil cliente se eu usar dessa forma fica muito lenta a consulta

    um amigo sugeriu eu usar um raw xml.

    mais não tenho ideia de como implementa isso.

    Rhael,

    Eu não tinha visto esta parte de ficar lenta a sua query.... Neste caso a subquery dentro na junção realmente não vai ajudar.


    Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]

    terça-feira, 25 de junho de 2019 12:13
  • José Diz a consulta ficou mais rápida do que estava antes esta demorando 1:02 e passou a demora 0:16

    vc teria um outro abordagem pra melhora ainda mais essa buscar?

    Rhael, qual é a chave primária da tabela clienteend?

    Se a chave primária for { cnpj_cpf_end, cod_end }, então a associação entre as tabelas clienteend e cliente será rápida.



    José Diz     Belo Horizonte, MG - Brasil     [T-SQL performance tuning: Porto SQL]   [e-mail]


    Este conteúdo é fornecido sem garantias de qualquer tipo, seja expressa ou implícita.

    • Editado José Diz terça-feira, 25 de junho de 2019 12:50
    terça-feira, 25 de junho de 2019 12:13
  • Rhael,

    O exemplo de código do José Diz, esta coerente!

    Talvez transformar esta query em uma view, poderá lhe ajudar um pouquinho mais:

    Create View V_DadosClientesEnderecos
    As
    Select C.NomeCliente,
           (Select Top 1 CE.Logradouro from ClientesEnderecos CE
            where CE.CodigoCliente = C.CodigoCliente
            Order By CE.CodigoEndereco Desc) As Endereco
    From Clientes C 
    Go
    
    Select * From V_DadosClientesEnderecos
    Go

    Podemos também pensar quem sabe no uso de uma CTE:

    ;With CTE_DadosClientesEnderecos
    As
    (
    
    Select C.NomeCliente,
           (Select Top 1 CE.Logradouro from ClientesEnderecos CE
            where CE.CodigoCliente = C.CodigoCliente
            Order By CE.CodigoEndereco Desc) As Endereco
    From Clientes C 
    
    )
    Select * From CTE_DadosClientesEnderecos
    Go

    Destaco e ressalto que estes dois trechos de código aqui exemplicados, foram criados com base, no código fonte criado e publicado pelo José Diz, sendo assim, os direitos autorias pertencem a ele.

    O importante neste caso, é justamente estabelecer as junções utilizando suas chaves primárias para fazer uso dos índices, bem como, estabelecer as condições com parâmetros que satisfaçam a busca pelos dados.

    Desculpe-me na minha primeira resposta, eu não havia percebido que no final do seu post, você esta se referindo a lentidão, eu havia entendido que a pergunta era sobre a dúvida para montar a query.


    Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]


    • Editado Junior Galvão - MVPMVP terça-feira, 25 de junho de 2019 12:46 Atualização da resposta e acréscimo dos exemplos de código.
    • Sugerido como Resposta IgorFKModerator terça-feira, 25 de junho de 2019 13:26
    terça-feira, 25 de junho de 2019 12:15