Pular para o conteúdo
  • Este tópico contém 1 resposta, 2 vozes e foi atualizado pela última vez 6 anos, 10 meses atrás por Avatar photoJosé Laurindo Chiappa.
Visualizando 2 posts - 1 até 2 (de 2 do total)
  • Autor
    Posts
  • #109120
    Avatar de rafaelgrafaelg
    Participante

      Pessoal boa tarde, estou iniciando um select mas me deparei com um problema. Eu tenho duas tabelas uma de nome do cliente e a outra com o histórico da venda do cliente:

      Cliente
      cod_cli
      Nome_cli

      Historico_Venda
      cod Venda
      Total
      Cod_Cli
      Cod_Cli_Consumidor

      Quando é feita uma venda do tipo consumidor o código do cliente é salvo no campo Cod_Cli_Consumidor e no campo Cod_Cli é salvo o código de um usuário “consumidor padrão” e quando a venda é feita com no nome do cliente o codigo do cliente é salvo no campo Cod_Cli. Eu preciso de um select que retorne o nome do cliente verdadeiro e não do “consumidor padrão”, algo do tipo:

      Select cli.cod, cli.nome_cli, hist.total
      From Cliente cli, Historico_venda hist
      Where cli.cod = hist.Cod_cli
      or
      cili.cod = hist.Cod_Cli_Consumidor

      #109121
      Avatar photoJosé Laurindo Chiappa
      Moderador

        Blz ? Então, em primeiro lugar eu ** tenho ** que dizer que essa tua Modelagem é meio BASTANTE questionável : pra começo de conversa, ao que entendo o fato de ser ou não um ‘Consumidor padrão’ é um ATRIBUTO do cliente, então as regras de Normalização rezam que tal atributo DEVERIA estar na entidade CLIENTE, aonde pertence, né não ?? Outra coisa é usar uma coluna com valor artificial ao invés de simplesmente ter uma FLAG, com um domínio definido (0 ou 1, S ou N, o que for) pra indicar se é ‘consumidor padrão’….
        Mas ok : ao que entendo, na coluna Cod_Cli da tabela HISTORICO_VENDA nós ** OU ** teremos um ‘código-padrão’ (que vc não diz qual é, vou supor aqui que seja 9999, digamos) e nesse caso o código ‘real’ a se fazer o JOIN com a tabela Cliente vai estar na coluna Cod_Cli_Consumidor ** OU ** então, se Historico_Venda.Cod_cli é DIFERENTE do valor-padrão, aí esse é o código ‘real’…. Se for isso, para vc fazer um IF , uma ‘condição’ que retorne um ou outro valor, a possibilidade maior na linguagem SQL é vc usar um CASE, vc pode pensar nele como um IF que retorna um valor para cada condição… Acho que seria + ou – assim (novamente, SUPONDO que o tal ‘valor-padrão’ é 9999) :

        ==> crio as tabelas :

        scott@DESENV:SQL>create table Cliente(
        2 cod_cli number,
        3 Nome_cli varchar2(80) );

        Tabela criada.

        scott@DESENV:SQL>create table Historico_Venda(
        2 cod_Venda number,
        3 Total number,
        4 Cod_Cli number,
        5* Cod_Cli_Consumidor number );

        Tabela criada.

        ==> Vou ter dois clientes como massinha de testes :

        scott@DESENV:SQL>insert into Cliente values(1, ‘Cliente 1’);

        1 linha criada.

        scott@DESENV:SQL>insert into Cliente values(2, ‘Cliente 2’);

        1 linha criada.

        => Vou ter duas vendas no exemplo – a primeira, com o código de venda 10 pro cliente 1, que (digamos) ** não ** é Consumidor então na coluna Cod_cli ** não ** vai estar o valor-padrão e sim o seu código 1, ‘real’, e na coluna Cod_Cli_Consumidor um valor qualquer, zero null, 9999, não importa : o importante aqui na minha lógica pressuposta é que quando Cod_cli estiver DIFERENTE do valor-padrão é ESSE valor que deve ir pro JOIN, não importando o que estiver em Cod_cli_Consumidor :

        scott@DESENV:SQL>insert into Historico_venda values(10, 100, 1, 9999);

        1 linha criada.

        => e OUTRA venda com código 20 pro cliente 2, que (digamos) É SIM um cliente ‘consumidor e PORTANTO na coluna Cod_cli VAI ESTAR SIM o valor-padrão E PORTANTO em Cod_Cli_Consumidor vai estar o valor ‘real’ do cliente, 2 neste caso :

        scott@DESENV:SQL>insert into Historico_venda values(20, 200, 9999, 2);

        1 linha criada.

        ==> è só codificar em SQL o que dissemos em Português, ou seja : retorno como valor para o JOIN a coluna Cod_Cli_Consumidor se Cod_cli for igual ao valor-padrão, ou senão retorne o próprio valor de Cod_cli :

        scott@DESENV:SQL>Select hist.cod_venda, cli.cod_cli, cli.nome_cli, hist.total
        2 From Cliente cli, Historico_venda hist
        3* Where cli.cod_cli = CASE WHEN hist.Cod_cli = 9999 THEN Cod_Cli_Consumidor ELSE hist.Cod_cli end;

        COD_VENDA COD_CLI NOME_CLI TOTAL
        ——— ——— ———— ———
        10 1 Cliente 1 100
        20 2 Cliente 2 200

        scott@DESENV:SQL>

        ==> Como eu disse pra mim essa Modelagem está TORTINHA DA SILVA (pois os campos-chave DEVERIAM ser valores atômicos e únicos, quase sempre que vc tem que usar função de conversão E/OU funções de IF e/ou tem qquer tipo de retrabalho num valor-chave isso imho é indicação CLARA de normalização não-OK ou de datatype impróprio ou coisa assim), mas as funções em si existem e funcionam…

        []s

        Chiappa

      Visualizando 2 posts - 1 até 2 (de 2 do total)
      • Você deve fazer login para responder a este tópico.
      plugins premium WordPress