7 Replies Latest reply: Dec 8, 2016 1:30 PM by Guilherme Dorow RSS

    Dificuldades com Inner Join

    Guilherme Dorow

      Olá!

      Sou iniciante no qlik e tenho uma dúvida que não consegui solucionar sozinho até o presente momento.

      Estou montando uma análise para avaliar a quantidade de produtos produzidos, abaixo está o sql que montei e extrai tudo perfeitamente mas no qlik não consigo relacionar as tabelas corretamente com o inner join.

       

       

      No qlik criei uma tabela Fato para a minha tabela PRODUCAO e nessa tabela eu tenho apenas os códigos, as descrições ficam separadas nas outras tabelas, por isso a necessidade do inner join.

       

       

      Tentei ligar direto, relacionando por exemplo código sub grupo da tabela producao com o código sub grupo da tabela subgrupo_01 porém o problema é que, o subgrupo 001 é feijão quando está no grupo 001 e sorvete quando está no grupo 002. O mesmo problema ocorre com o item, por isso a necessidade desse relacionamento abaixo.

       

       

      Vocês conseguem me dar uma luz de como posso proceder com esse relacionamento?

       

       

      OBS.: montei uma visualização só com os códigos (apenas com a tabela producao) sem as descrições e ficou perfeita, quando relaciono com as demais tabelas para trazer a descrição que embaralha tudo.

       

       

      SELECT  PRO.COD_OPERADOR,

             USR.NOME_OPERADOR,

              PRO.NIVEL,

              PRO.GRUPO,

              PRO.SUBGRUPO,

             SUB.DESCR_SUBGR,

              PRO.ITEM,

             ITE.NARRATIVA,

             COL.COLECAO,

             COL.DESCR_COLECAO,

              PRO.NOTA_ENTRADA,

              PRO.SERIE_NOTA,

              PRO.CNPJ9_FORN,

              PRO.CNPJ4_FORN,

              PRO.CNPJ2_FORN,

             FRN.NOME_FORNECEDOR,

              PRO.DATA_PRODUCAO,

              PRO.PESO

            

        FROM PRODUCAO  PRO

         

          INNER JOIN GRUPO_01 GRU ON (GRU.NIVEL =  PRO.NIVEL AND

                                      GRU.REFERENCIA      =  PRO.GRUPO)

         

          INNER JOIN SUBGRUPO_01 SUB ON (SUB.NIVEL_S =  PRO.NIVEL AND

                                      SUB.GRUPO_S =  PRO.GRUPO   AND

                                      SUB.SUBGRUPO_S      =  PRO.SUBGRUPO)

         

          INNER JOIN ITEM_01 ITE ON (ITE.NIVEL_E  =  PRO.NIVEL  AND

                                      ITE.GRUPO_E  =  PRO.GRUPO    AND

                                      ITE.SUBGRU_E =  PRO.SUBGRUPO AND

                                      ITE.ITEM_E   =  PRO.ITEM)

         

          INNER JOIN COL_01 COL ON (COL.COLECAO = GRU.COLECAO)

         

          INNER JOIN FORNE_01 FRN ON (FRN.FORNECEDOR9 =  PRO.CNPJ9_FORN AND

                                      FRN.FORNECEDOR4 =  PRO.CNPJ4_FORN AND

                                      FRN.FORNECEDOR2 =  PRO.CNPJ2_FORN)

       

       

       

       

          INNER JOIN OPERADOR_01 USR ON (USR.CODIGO_USUARIO =  PRO.COD_OPERADOR)

       

       

       

       

      WHERE  PRO.DATA_PRODUCAO BETWEEN

            TO_DATE('11/05/2016', 'DD/MM/YYYY') --Data inicial

        AND TO_DATE('11/05/2016', 'DD/MM/YYYY') --Data final

       

      GROUP BY

              PRO.COD_OPERADOR,

              USR.NOME_OPERADOR,

              PRO.NIVEL,

              PRO.GRUPO,

              PRO.SUBGRUPO,

             SUB.DESCR_SUBGR,

             PRO.ITEM,

             ITE.NARRATIVA,

             COL.COLECAO,

             COL.DESCR_COLECAO,

              PRO.NOTA_ENTRADA,

              PRO.SERIE_NOTA,

              PRO.CNPJ9_FORN,

              PRO.CNPJ4_FORN,

              PRO.CNPJ2_FORN,

              FRN.NOME_FORNECEDOR,

              PRO.DATA_PRODUCAO,

              PRO.PESO

       

       

      Desde já agradeço a todos da comunidade

        • Re: Dificuldades com Inner Join
          Alessandro Furtado

          Guilherme,

           

          normalmente tento trazer into para o Qlik

           

          exemplo:

          LOAD

                GRUPO              as Grupo_Codigo;

          SELECT  GRUPO  FROM PRODUCAO;

           

          left join

           

          LOAD

                GRUPO              as Grupo_Codigo,

                 DES_GRUPO    as Grupo_Descricao;

          SELECT  GRUPO , DES_GRUPO FROM GRUPO;

           

          a descrição pode ser pega usando um applymap também......ou com join......

           

           

          Somente deixo no SQL quando a performance ser muito diferente e ai deixo o banco resolver. Mas na grande maioria do tempo, sempre resolvo no Qlik.  Mas ai depende de cada um.......

            • Re: Dificuldades com Inner Join
              Guilherme Dorow

              Olá Alessandro,

              Obrigado por responder!

               

              Tentei com o left join como você explicou acima, mas ele criou chaves sintéticas e pelo que andei lendo essas chaves sintéticas não são boas de serem criadas certo?

               

              O problema começa no subgrupo e item.

               

              Exemplo abaixo:

              bala de goma pertence ao grupo 2 subgrupo 1 e item 1

              arroz pertence ao grupo 1 subgrupo 1 e item 1

               

              veja que os produtos acima pertencem ao mesmo subgrupo e item, mas são diferentes. No SQL que coloquei na pergunta está funcionando por isso anexei ele, mas no qlik não consegui relacionar dessa forma.

               

              O Qlik só permite 1 campo de comparação para relacionar as tabelas, por exemplo se eu coloco o campo GRUPO no grupo, no subgrupo e no item ele da erro..

            • Re: Dificuldades com Inner Join
              Wellington Regis Silva

                  Guilherme,

                  Saúde e Paz!

               

                  Uma das alternativas é concatenar os campos chaves para criar um único campo de ligação. Veja minha sugestão de como ficaria seu Script com essa alternativa:

               

              LOAD *, NUM(GRUPO, '00')&'|'&NUM(SUBGRUPO, '00') AS ID_CLASSE;
              SQL
              SELECT
              PRO.COD_OPERADOR,
              USR.NOME_OPERADOR,
              PRO.NIVEL,
              PRO.GRUPO,
              PRO.SUBGRUPO,
              SUB.DESCR_SUBGR,
              PRO.ITEM,
              ITE.NARRATIVA,
              COL.COLECAO,
              COL.DESCR_COLECAO,
              PRO.NOTA_ENTRADA,
              PRO.SERIE_NOTA,
              PRO.CNPJ9_FORN,
              PRO.CNPJ4_FORN,
              PRO.CNPJ2_FORN,
              FRN.NOME_FORNECEDOR,
              PRO.DATA_PRODUCAO,
              PRO.PESO
              FROM
              PRODUCAO PRO
              INNER JOIN GRUPO_01 GRU
              ON
              GRU.NIVEL        = PRO.NIVEL
              AND GRU.REFERENCIA = PRO.GRUPO
              INNER JOIN SUBGRUPO_01 SUB
              ON
              SUB.NIVEL_S      = PRO.NIVEL
              AND SUB.GRUPO_S    = PRO.GRUPO
              AND SUB.SUBGRUPO_S = PRO.SUBGRUPO
              INNER JOIN ITEM_01 ITE
              ON
              ITE.NIVEL_E    = PRO.NIVEL
              AND ITE.GRUPO_E  = PRO.GRUPO
              AND ITE.SUBGRU_E = PRO.SUBGRUPO
              AND ITE.ITEM_E   = PRO.ITEM
              INNER JOIN COL_01 COL
              ON
              COL.COLECAO = GRU.COLECAO
              INNER JOIN FORNE_01 FRN
              ON
              FRN.FORNECEDOR9   = PRO.CNPJ9_FORN
              AND FRN.FORNECEDOR4 = PRO.CNPJ4_FORN
              AND FRN.FORNECEDOR2 = PRO.CNPJ2_FORN
              INNER JOIN OPERADOR_01 USR
              ON
              USR.CODIGO_USUARIO = PRO.COD_OPERADOR
              WHERE
              PRO.DATA_PRODUCAO BETWEEN TO_DATE('11/05/2016', 'DD/MM/YYYY') --Data inicial
              AND TO_DATE('11/05/2016', 'DD/MM/YYYY')                         --Data final
              GROUP BY
              PRO.COD_OPERADOR,
              USR.NOME_OPERADOR,
              PRO.NIVEL,
              PRO.GRUPO,
              PRO.SUBGRUPO,
              SUB.DESCR_SUBGR,
              PRO.ITEM,
              ITE.NARRATIVA,
              COL.COLECAO,
              COL.DESCR_COLECAO,
              PRO.NOTA_ENTRADA,
              PRO.SERIE_NOTA,
              PRO.CNPJ9_FORN,
              PRO.CNPJ4_FORN,
              PRO.CNPJ2_FORN,
              FRN.NOME_FORNECEDOR,
              PRO.DATA_PRODUCAO,
              PRO.PESO;

               

                 Observe que o comando "LOAD *, NUM(GRUPO, '00')&'|'&NUM(SUBGRUPO, '00') AS ID_CLASSE;" vai carregar todos os campos do comando SELECT  e concatenar os campos chaves para formar um único. Você deve usar essa expressão para montar os mesmo campos nas outras tabelas. Assim você acabará com as chaves sintéticas.

                  Se sua base de dados for muito grande você poderá usar "autonumber", "autonumberhash128" ou "autonumberhash256" para criar chaves primárias. Mas a primeira ideia que lhe dei torna os campos mais intuitivos.

               

                  Espero ter podido ajudar...

               

              Felicidades...

                • Re: Dificuldades com Inner Join
                  Guilherme Dorow

                  Wellington,

                  Muito obrigado!

                   

                  Fiz conforme você explicou e ficou perfeito! Só fiquei com uma dúvida, com essa forma que você me passou foi criado uma tabela com todas as informações corretas que preciso, e apenas adicionei um calendário conforme figura abaixo:

                  Capturar.JPG

                  É Correto trabalhar dessa forma ou você recomendaria manter apenas os campos chaves e relacionar esses campos  com as outras tabelas?

                   

                  De verdade, muito obrigado!!

                    • Re: Dificuldades com Inner Join
                      Wellington Regis Silva

                          Oi Guilherme,

                          Fico feliz que tenha funcionado

                       

                          É correto sim trabalhar dessa forma. Mas você tem que converter a data num campo de texto para evitar "confusões" por conta dos diversos formatos que um campo de data pode ser interpretado.

                         Vou te passar um Scrip de gera um QVD com um calendário completo, marcando os dias úteis ou não. Nele você poderá adicionar os feriados municipais e estaduais que desejar, além de datas comemorativas. Essas informações podem lhe ser muito úteis para cálculos com dia úteis. Eu adaptei esse Script para colocar os feriados com datas móveis. O cálculo é complexo mas é bem rápido pra gerar (meu PC gera um calendário de 4 anos em menos de um segundo). Lá vai

                       

                      //   Iniciar as variáveis que determinarão o intervalo do calendário
                      LET V_DATA_INI = MakeDate( Year( Today())-4, 1, 1); 
                      LET V_DATA_FIN = YearEnd( Today());

                      LET V_ANO = Year( V_DATA_INI);
                      LET V_ANO_FIN = Year( V_DATA_FIN);


                      DIRECTORY;

                      DO WHILE V_ANO <= V_ANO_FIN


                      LET V_C01 = Floor( V_ANO/100);
                      LET V_C02 = V_ANO - (19*Floor( V_ANO /19));
                      LET V_C03 = Floor((V_C01 - 17)/25);
                      LET V_C04 = V_C01 - Floor(V_C01/4) - Floor((V_C01-V_C03)/3) +(19*V_C02) + 15;
                      LET V_C05 = V_C04 - (30*Floor(V_C04/30));
                      LET V_C06 = V_C05 - (Floor(V_C05/28)*(1-Floor(V_C05/28))*Floor(29/(V_C05+1))*Floor((21-V_C02)/11));
                      LET V_C07 = V_ANO + Floor(V_ANO/4) + V_C06 + 2 -V_C01 + Floor(V_C01/4);
                      LET V_C08 = V_C07 - 7*Floor(V_C07/7);
                      LET V_C09 = V_C06 - V_C08;
                      LET V_MES = 3 + Floor((V_C09+40)/44);
                      LET V_DIA = V_C09 + 28 - (31*Floor(V_MES/4));
                      SET V_Pascoa =  'MakeDate( $(V_ANO), $(V_MES), $(V_DIA))';

                      FERIADOS:

                      // Para adicionar um novo feriado insira a linha de comando da seguinte forma: "LOAD  $(V_ANO) & 'MM' & 'DD' as Id_Calendario, 'Nome_do_Feriado' as Feriado AutoGenerate(1);"
                      // Substituindo MM pelo número do mês e DD pelo dia; ambos com dois algarismos
                          
                      LOAD  $(V_ANO) & Num($(V_MES),'00') & Num($(V_DIA),'00') as Id_Calendario, 'Páscoa' as Feriado AutoGenerate(1);
                      LOAD  $(V_ANO) & Num( Month( $(V_Pascoa) - 47), '00') & Num( Day($(V_Pascoa) - 47), '00') as Id_Calendario, 'Carnaval' as Feriado AutoGenerate(1);
                      LOAD  $(V_ANO) & Num( Month( $(V_Pascoa) - 2), '00') & Num( Day( $(V_Pascoa) - 2), '00') as Id_Calendario, 'Paixão de Cristo' as Feriado AutoGenerate(1);
                      LOAD  $(V_ANO) & Num( Month( $(V_Pascoa) + 60), '00') & Num( Day( $(V_Pascoa) + 60), '00') as Id_Calendario, 'Corpus Cristi' as Feriado AutoGenerate(1);    
                      LOAD  $(V_ANO) & '01' & '01' as Id_Calendario, 'Confraternização Universal' as Feriado AutoGenerate(1);
                      LOAD  $(V_ANO) & '04' & '21' as Id_Calendario, 'Tiradentes' as Feriado AutoGenerate(1);
                      LOAD  $(V_ANO) & '05' & '01' as Id_Calendario, 'Dia do Trabalhador' as Feriado AutoGenerate(1);
                      LOAD  $(V_ANO) & '09' & '07' as Id_Calendario, 'Independência' as Feriado AutoGenerate(1);
                      LOAD  $(V_ANO) & '10' & '12' as Id_Calendario, 'Nossa Senhora Aparecida' as Feriado AutoGenerate(1);
                      LOAD  $(V_ANO) & '11' & '02' as Id_Calendario, 'Finados' as Feriado AutoGenerate(1);
                      LOAD  $(V_ANO) & '11' & '15' as Id_Calendario, 'Proclamação da República' as Feriado AutoGenerate(1);
                      LOAD  $(V_ANO) & '12' & '25' as Id_Calendario, 'Natal' as Feriado AutoGenerate(1);

                      DATAS_COMEMORATIVAS:

                      // Para adicionar uma nova data comemorativa insira a linha de comando da seguinte forma:
                      //"LOAD  $(V_ANO) & 'MM' & 'DD' as Id_Calendario, 'Nome_Da_Data_Comemorativa' as Dt_Comemorativa AutoGenerate(1);"
                      // Substituindo MM pelo número do mês e DD pelo dia; ambos com dois algarismos
                          
                      LOAD  $(V_ANO) & '10' & '30' as Id_Calendario, 'Emancipação Política de Arapiraca' as Dt_Comemorativa  AutoGenerate(1);
                      LOAD  $(V_ANO) & '09' & '16' as Id_Calendario, 'Emancipação Política de Alagoas' as Dt_Comemorativa AutoGenerate(1);
                      LOAD  $(V_ANO) & '02' & '02' as Id_Calendario, 'N.S. do Bom Conselho' as Dt_Comemorativa AutoGenerate(1);
                      LOAD  $(V_ANO) & '10' & '17' as Id_Calendario, 'Dia do Eletricista' as Dt_Comemorativa AutoGenerate(1);
                      LOAD  $(V_ANO) & '11' & '20' as Id_Calendario, 'Consciência Negra' as Dt_Comemorativa AutoGenerate(1);
                      LOAD  $(V_ANO) & '12' & '31' as Id_Calendario, 'Revellion' as Dt_Comemorativa AutoGenerate(1);
                      LOAD  $(V_ANO) & '12' & '08' as Id_Calendario, 'N.S. da Conceição' as Dt_Comemorativa AutoGenerate(1);
                      LOAD  $(V_ANO) & '06' & '13' as Id_Calendario, 'Santo Antonio' as Dt_Comemorativa AutoGenerate(1);
                      LOAD  $(V_ANO) & '06' & '24' as Id_Calendario, 'São João' as Dt_Comemorativa AutoGenerate(1);
                      LOAD  $(V_ANO) & '06' & '29' as Id_Calendario, 'São Pedro' as Dt_Comemorativa AutoGenerate(1);
                      LOAD  $(V_ANO) & '10' & '15' as Id_Calendario, 'Dia dos Professores' as Dt_Comemorativa AutoGenerate(1);

                      LET V_ANO = V_ANO +1;
                      LOOP;


                      Calendario_Temp:
                      LOAD
                      //   Date( Data, 'DD/MM/YYYY' ) as Data,
                           Data,
                      Num( Day( Data ), '00' ) as DIA,
                      Month( Data ) as MES,
                      Year( Data ) as ANO,
                      DayNumberOfQuarter( Data ) as [Dia Trimestre],
                      DayNumberOfYear( Data ) as [Dia Ano],
                      MonthName( Data ) as [Mes Ano],
                      QuarterName( Data ) as Quarter,
                      Week( Data ) as Semana,
                      Ceil( Month( Data ) / 3 )&'º Trim' as Trimestre,
                      WeekDay( Data ) as [Dia Semana],
                      //   ApplyMap( 'MapDias', Text( WeekDay( Data ) ) ) as [N° Dia Semana],
                           AutoNumber( Data ) as Sequencial,
                      If( WeekDay( Data )= 'DOM' or WeekDay( Data )= 'SAB', 0, 1 ) as DiaUtil_Temp,
                      Year( Data )&Num( Month( Data ), 00 ) as [Ano Mes],
                      Year( Data )&Num( Month( Data ),'00')&Num( Day( Data ), '00' ) as Id_Calendario;

                      LOAD
                      //   Date( MonthEnd( Today() ) - Recno(), 'DD/MM/YYYY' ) as Data
                                 Date( YearEnd(Today())+1 - Recno()) as Data

                      AutoGenerate( V_DATA_FIN+1 - V_DATA_INI );

                      Left Join

                      LOAD * Resident FERIADOS;

                      Left Join

                      LOAD * Resident DATAS_COMEMORATIVAS;

                      Calendario:
                      LOAD Data,
                      DIA,
                      MES,
                      ANO,
                      [Dia Trimestre],
                      [Dia Ano],
                      [Mes Ano],
                      Quarter,
                      Semana,
                      Trimestre,
                      [Dia Semana],
                      Sequencial,
                      [Ano Mes],
                      Id_Calendario,
                      Feriado,
                      Dt_Comemorativa
                      ,
                      If( Len(Feriado),0,DiaUtil_Temp) as DiaUtil;
                      LOAD * Resident Calendario_Temp;

                      STORE Calendario into Calendario.qvd (qvd);
                      //STORE Calendario into .\TRANSFORMACAO\Calendario.qvd (qvd);
                      //STORE Calendario into \\Servarquivos\Clandestinos_AT\QVDs\Calendario.qvd (qvd);

                      Drop Tables FERIADOS, DATAS_COMEMORATIVAS, Calendario_Temp, Calendario;



                          Adapte para seu uso e se divirta!


                      Felicidaesdes...