Retornar apenas 1. linha de consulta em outra tabela.

Dúvidas, dicas e truques de PL/SQL. Aqui também vão assuntos relacionados a pacotes, triggers, funções, Java-Stored Procedures, etc
Responder
Toni_Jr
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 6
Registrado em: Qua, 18 Dez 2019 10:30 am

Pessoal boa tarde!

Fiz uma pesquisa no fórum, porem não encontrei algo que me ajude.
Tenho uma consulta na qual preciso adicionar outros dois campos de outra tabela, porem não queria trazer todas as linhas, mas sim apenas o primeiro registro referente ao meu codcli.

Tentei rownum dentro de uma subquery, mas não consigo trazer apenas a primeira linha, que é o que me interessa.

Se alguém tiver uma ideia :D ... estrou travado nesse ponto, e não brilhou nenhuma ideia ainda..... :?

Valeu...!

Selecionar tudo

select
    c.cgcent as "CPF/CNPJ",
    c.codcli as "Cod. Cliente",
    c.cliente as "Cliente",
    c.telent as "Telefone",
    c.codusur1 as "RCA",
    u.nome as "Vendedor",
    c.email as "Mail" ,
    c.observacao_pc as "Observacoes",
    decode(c.obs, 'A','Aprovado','P','Pendente') as "Status",
    c.dtinclusao as "Inclusao" , 
    c.dtalteracao as "Alteracao",
    sum(o.vltotal) as "R$ ORC",
    count(o.numorca) as "QTD ORC",
    sum(f.vltotal) as "R$ NF",
    count(f.numnota) as "QTD Notas",
    i.dtprimcompra as "Primeira NF",
    i.dtultcomp as "Ultima NF",
    i.codatv1 as "Cod. Atividade",
    a.ramo as "Ramo",
    e.codvisita as "Visita", -- apenas o primeiro, 
    e.assunto as "Assunto" -- apenas o primeiro
    
from
    pcclientfv    c,
    pcvisita      e,  -- tabela campo "assunto"
    pcusuari      u, 
    pcnfsaid      f,
    pcclient      i,
    pcativi       a,
    pcorcavendac  o

where 
    c.dtinclusao >= : data_ini         --'01/12/19'
    and c.dtinclusao <= : data_fim     --'31/12/19'
    and c.codusur1 = u.codusur
    and c.codcli = f.codcli(+)
    and c.codcli = e.codcli(+)
    and c.codcli = o.codcli(+)
    and c.codcli = i.codcli(+)
    and i.codatv1 = a.codativ(+)
    and (c.observacao_pc like '%INBOUND%'
            or (c.observacao_pc like '%OUTBOUND%' 
                or (c.observacao_pc like '%SITE%'
                    or (c.observacao_pc like '%FACEBOOK%'
                        or (c.observacao_pc like '%LINKEDIN%'
                            or (c.observacao_pc like '%WHATSAPP%'
                                or (c.observacao_pc like '%CHAT%'      
                                   )   
                               ) 
                           )  
                       )  
                   )
               )
        ) 
        
group by 
    c.cgcent, 
    c.codcli, 
    c.cliente, 
    c.telent, 
    c.codusur1, 
    u.nome, 
    c.email, 
    c.observacao_pc, 
    decode(c.obs, 'A','Aprovado','P','Pendente'), 
    c.obs, 
    c.dtinclusao, 
    c.dtalteracao, 
    i.dtprimcompra, 
    i.dtultcomp, 
    i.codatv1, 
    a.ramo ,
    e.assunto, 
    e.codvisita  


order by
    c.dtinclusao
Avatar do usuário
dr_gori
Moderador
Moderador
Mensagens: 5024
Registrado em: Seg, 03 Mai 2004 3:08 pm
Localização: Portland, OR USA
Contato:
Thomas F. G

Você já respondeu a dúvida de alguém hoje?
https://glufke.net/oracle/search.php?search_id=unanswered

Deixa eu ver se eu entendi:

A tabela pcvisita pode ter várias linhas.
E você quer que ele só traga a primeira ?

Se é isso, eu acho que você pode fazer assim:

1. Tira do GROUP BY essas duas linhas:

Selecionar tudo

 e.assunto,
 e.codvisita 
2. No SELECT coloca:

Selecionar tudo

MIN(e.codvisita) as "Visita" -- apenas o primeiro,
Depois a gente busca o assunto.
Veja se isso é o que você precisa por enquanto na sua query.
Avatar do usuário
dr_gori
Moderador
Moderador
Mensagens: 5024
Registrado em: Seg, 03 Mai 2004 3:08 pm
Localização: Portland, OR USA
Contato:
Thomas F. G

Você já respondeu a dúvida de alguém hoje?
https://glufke.net/oracle/search.php?search_id=unanswered

Se você quiser que seja o primeiro baseado em alguma data, nos mande qual é a estrutura da tabela!
Toni_Jr
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 6
Registrado em: Qua, 18 Dez 2019 10:30 am

Exato meu caro!

Na tabela pcvisita é inserido todos os registros, sendo o codvisita o pk.

Selecionar tudo

-------------- -------- -------------- 
CODVISITA      NOT NULL NUMBER(10)     
CODCLI                  NUMBER(6)      
DATA                    DATE           
CODMOTIVO               NUMBER(6)      
CODOPERADORA            NUMBER(8)      
ASSUNTO                 VARCHAR2(4000) 
O que me interessa nessa consulta, é apenas o primeiro registro referente a cada codcli.

A primeira limitação usando o MIN foi :D
Avatar do usuário
dr_gori
Moderador
Moderador
Mensagens: 5024
Registrado em: Seg, 03 Mai 2004 3:08 pm
Localização: Portland, OR USA
Contato:
Thomas F. G

Você já respondeu a dúvida de alguém hoje?
https://glufke.net/oracle/search.php?search_id=unanswered

Outra forma de fazer isso é limitar na cláusula FROM.
(Mas se sua tabela for gigante, eu acho que não ia optar por essa opção).

Veja esse exemplo: Tabela EMP:

Selecionar tudo

SQL> select deptno, empno, ename, hiredate
  2  from emp
  3  order by deptno, hiredate
  4  /

DEPTNO EMPNO ENAME      HIREDATE
------ ----- ---------- -----------
    10  7782 CLARK      09-Jun-81
    10  7839 KING       17-Nov-81
    10  7934 MILLER     23-Jan-82
    20  7369 SMITH      17-Dec-80
    20  7566 JONES      02-Apr-81
    20  7902 FORD       03-Dec-81
    20  7788 SCOTT      09-Dec-82
    20  7876 ADAMS      12-Jan-83
    30  7499 ALLEN      20-Feb-81
    30  7521 WARD       22-Feb-81
    30  7698 BLAKE      01-May-81
    30  7844 TURNER     08-Sep-81
    30  7654 MARTIN     28-Sep-81
    30  7900 JAMES      03-Dec-81

14 rows selected
Digamos que eu estou interessado apenas no registro MAIS ANTIGO de cada DEPTNO.
Aí, usando funções analíticas -- https://glufke.net/oracle/download/funco ... TICAS.html

Eu coloco um ROWNUMBER pela DATA (Hiredate)

Selecionar tudo

SQL> select deptno, empno, ename, hiredate
  2  ,ROW_NUMBER()
  3      OVER (PARTITION BY deptno
  4            ORDER BY hiredate) SEQ
  5  from emp
  6  order by deptno, hiredate
  7  ;

DEPTNO EMPNO ENAME      HIREDATE           SEQ
------ ----- ---------- ----------- ----------
    10  7782 CLARK      09-Jun-81            1    --MAIS ANTIGO do dept 10
    10  7839 KING       17-Nov-81            2
    10  7934 MILLER     23-Jan-82            3
    20  7369 SMITH      17-Dec-80            1   --MAIS ANTIGO do dept 20
    20  7566 JONES      02-Apr-81            2
    20  7902 FORD       03-Dec-81            3
    20  7788 SCOTT      09-Dec-82            4
    20  7876 ADAMS      12-Jan-83            5
    30  7499 ALLEN      20-Feb-81            1  --MAIS ANTIGO do dept 30
    30  7521 WARD       22-Feb-81            2
    30  7698 BLAKE      01-May-81            3
    30  7844 TURNER     08-Sep-81            4
    30  7654 MARTIN     28-Sep-81            5
    30  7900 JAMES      03-Dec-81            6

14 rows selected
Agora, basta filtrar tudo que é 1:

Selecionar tudo

SQL> select *
  2  from (
  3        select deptno, empno, ename
  4        ,ROW_NUMBER()
  5            OVER (PARTITION BY deptno
  6                  ORDER BY hiredate) SEQ
  7        from emp
  8        order by deptno, hiredate
  9        )
 10  where SEQ=1;

DEPTNO EMPNO ENAME             SEQ
------ ----- ---------- ----------
    10  7782 CLARK               1
    20  7369 SMITH               1
    30  7499 ALLEN               1

SQL> 
Toni_Jr
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 6
Registrado em: Qua, 18 Dez 2019 10:30 am

Com o exemplo que me passou , consigo buscar apenas o primeiro assunto de cada codcli,

Selecionar tudo

select ASSUNTO
 from (
        select CODVISITA, CODCLI,DATA, ASSUNTO
        ,ROW_NUMBER()
            OVER (PARTITION BY codcli
                  ORDER BY DATA) SEQ
        from pcvisita
        order by codcli
        )
 where SEQ = 1
Em um novo bloco funciona, mas colocando como subquery na minha consulta, retorna o erro de single-row.
Avatar do usuário
dr_gori
Moderador
Moderador
Mensagens: 5024
Registrado em: Seg, 03 Mai 2004 3:08 pm
Localização: Portland, OR USA
Contato:
Thomas F. G

Você já respondeu a dúvida de alguém hoje?
https://glufke.net/oracle/search.php?search_id=unanswered

Acho que a idéia é usar isso na cláusula FROM
Como se fosse uma tabela.

Algo assim:

Selecionar tudo

select
    c.cgcent as "CPF/CNPJ",
    c.codcli as "Cod. Cliente",
    c.cliente as "Cliente",
    c.telent as "Telefone",
    c.codusur1 as "RCA",
    u.nome as "Vendedor",
    c.email as "Mail" ,
    c.observacao_pc as "Observacoes",
    decode(c.obs, 'A','Aprovado','P','Pendente') as "Status",
    c.dtinclusao as "Inclusao" ,
    c.dtalteracao as "Alteracao",
    sum(o.vltotal) as "R$ ORC",
    count(o.numorca) as "QTD ORC",
    sum(f.vltotal) as "R$ NF",
    count(f.numnota) as "QTD Notas",
    i.dtprimcompra as "Primeira NF",
    i.dtultcomp as "Ultima NF",
    i.codatv1 as "Cod. Atividade",
    a.ramo as "Ramo",
    e.codvisita as "Visita", -- apenas o primeiro,
    e.assunto as "Assunto" -- apenas o primeiro
   
from
    pcclientfv    c,
------------ aqui a tabele E modificada
(
select *
from (
        select CODVISITA, CODCLI,DATA, ASSUNTO
        ,ROW_NUMBER()
            OVER (PARTITION BY codcli
                  ORDER BY DATA) SEQ
        from pcvisita
        order by codcli
        )
where SEQ = 1
) e, 
------ fim da tabela E

    pcusuari      u,
    pcnfsaid      f,
    pcclient      i,
    pcativi       a,
    pcorcavendac  o

where
    c.dtinclusao >= : data_ini         --'01/12/19'
    and c.dtinclusao <= : data_fim     --'31/12/19'
    and c.codusur1 = u.codusur
    and c.codcli = f.codcli(+)
    and c.codcli = e.codcli(+)
    and c.codcli = o.codcli(+)
    and c.codcli = i.codcli(+)
    and i.codatv1 = a.codativ(+)
    and (c.observacao_pc like '%INBOUND%'
            or (c.observacao_pc like '%OUTBOUND%'
                or (c.observacao_pc like '%SITE%'
                    or (c.observacao_pc like '%FACEBOOK%'
                        or (c.observacao_pc like '%LINKEDIN%'
                            or (c.observacao_pc like '%WHATSAPP%'
                                or (c.observacao_pc like '%CHAT%'     
                                   )   
                               )
                           ) 
                       ) 
                   )
               )
        )
       
group by
    c.cgcent,
    c.codcli,
    c.cliente,
    c.telent,
    c.codusur1,
    u.nome,
    c.email,
    c.observacao_pc,
    decode(c.obs, 'A','Aprovado','P','Pendente'),
    c.obs,
    c.dtinclusao,
    c.dtalteracao,
    i.dtprimcompra,
    i.dtultcomp,
    i.codatv1,
    a.ramo ,
    e.codvisita 
    e.assunto 


order by
    c.dtinclusao
Toni_Jr
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 6
Registrado em: Qua, 18 Dez 2019 10:30 am

Com a tua ajuda, consegui resolver assim:
Se tiver alguma ressalva, por favor... pode comentar! :D

Selecionar tudo

select
    c.cgcent                                        as "CPF/CNPJ",
    c.codcli                                        as "Cod. Cliente",
    c.cliente                                       as "Cliente",
    c.telent                                        as "Telefone",
    c.codusur1                                      as "RCA",
    u.nome                                          as "Vendedor",
    c.email                                         as "Mail" ,
    c.observacao_pc                                 as "Observacoes",
    decode(c.obs, 'A','Aprovado','P','Pendente')    as "Status",
    c.dtinclusao                                    as "Inclusao" , 
    c.dtalteracao                                   as "Alteracao",
    sum(o.vltotal)                                  as "R$ ORC",
    count(o.numorca)                                as "QTD ORC",
    sum(f.vltotal)                                  as "R$ NF",
    count(f.numnota)                                as "QTD Notas",
    i.dtprimcompra                                  as "Primeira NF",
    i.dtultcomp                                     as "Ultima NF",
    i.codatv1                                       as "Cod. Atividade",
    a.ramo                                          as "Ramo",
    MIN(e.codvisita)                                as "Visita A",
    MAX(e.codvisita)                                as "Visita Z", 
      
    (select pcvisita.assunto
       from pcvisita 
         where pcvisita.codvisita = (select min(pcvisita.codvisita)
                                       from pcvisita
                                         where pcvisita.codcli = c.codcli)) as "Primeiro Assunto",
     (select pcvisita.assunto
       from pcvisita 
         where pcvisita.codvisita = (select max(pcvisita.codvisita)
                                       from pcvisita
                                         where pcvisita.codcli = c.codcli)) as "Ultimo Assunto"                            
                                  
from
    pcclientfv    c,
    pcvisita      e,
    pcusuari      u, 
    pcnfsaid      f,
    pcclient      i,
    pcativi       a,
    pcorcavendac  o

where 
    c.dtinclusao >= : data_ini         --'01/12/19'
    and c.dtinclusao <= : data_fim     --'31/12/19'
    and c.codusur1 = u.codusur
    and c.codcli = f.codcli(+)
    and c.codcli = e.codcli(+)
    and c.codcli = o.codcli(+)
    and c.codcli = i.codcli(+)
    and i.codatv1 = a.codativ(+)
    and (c.observacao_pc like '%INBOUND%'
            or (c.observacao_pc like '%OUTBOUND%' 
                or (c.observacao_pc like '%SITE%'
                    or (c.observacao_pc like '%FACEBOOK%'
                        or (c.observacao_pc like '%LINKEDIN%'
                            or (c.observacao_pc like '%WHATSAPP%'
                                or (c.observacao_pc like '%CHAT%'      
                                   )   
                               ) 
                           )  
                       )  
                   )
               )
        ) 
        
group by 
    c.cgcent, 
    c.codcli, 
    c.cliente, 
    c.telent, 
    c.codusur1, 
    u.nome, 
    c.email, 
    c.observacao_pc, 
    decode(c.obs, 'A','Aprovado','P','Pendente'), 
    c.dtinclusao, 
    c.dtalteracao, 
    i.dtprimcompra, 
    i.dtultcomp, 
    i.codatv1, 
    a.ramo  

order by
    c.dtinclusao
   
--  '%INBOUND%'
--  '%OUTBOUND%' 
--  '%SITE%'
--  '%FACEBOOK%'
--  '%LINKEDIN%'
--  '%WHATSAPP%'
--  '%CHAT%'
Toni_Jr
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 6
Registrado em: Qua, 18 Dez 2019 10:30 am

Toni_Jr escreveu:Com a tua ajuda, consegui resolver assim:
Se tiver alguma ressalva, por favor... pode comentar! :D

Selecionar tudo

select
    c.cgcent                                        as "CPF/CNPJ",
    c.codcli                                        as "Cod. Cliente",
    c.cliente                                       as "Cliente",
    c.telent                                        as "Telefone",
    c.codusur1                                      as "RCA",
    u.nome                                          as "Vendedor",
    c.email                                         as "Mail" ,
    c.observacao_pc                                 as "Observacoes",
    decode(c.obs, 'A','Aprovado','P','Pendente')    as "Status",
    c.dtinclusao                                    as "Inclusao" , 
    c.dtalteracao                                   as "Alteracao",
    sum(o.vltotal)                                  as "R$ ORC",
    count(o.numorca)                                as "QTD ORC",
    sum(f.vltotal)                                  as "R$ NF",
    count(f.numnota)                                as "QTD Notas",
    i.dtprimcompra                                  as "Primeira NF",
    i.dtultcomp                                     as "Ultima NF",
    i.codatv1                                       as "Cod. Atividade",
    a.ramo                                          as "Ramo",
    MIN(e.codvisita)                                as "Visita A",
    MAX(e.codvisita)                                as "Visita Z", 
      
    (select pcvisita.assunto
       from pcvisita 
         where pcvisita.codvisita = (select min(pcvisita.codvisita)
                                       from pcvisita
                                         where pcvisita.codcli = c.codcli)) as "Primeiro Assunto",
     (select pcvisita.assunto
       from pcvisita 
         where pcvisita.codvisita = (select max(pcvisita.codvisita)
                                       from pcvisita
                                         where pcvisita.codcli = c.codcli)) as "Ultimo Assunto"                            
                                  
from
    pcclientfv    c,
    pcvisita      e,
    pcusuari      u, 
    pcnfsaid      f,
    pcclient      i,
    pcativi       a,
    pcorcavendac  o

where 
    c.dtinclusao >= : data_ini         --'01/12/19'
    and c.dtinclusao <= : data_fim     --'31/12/19'
    and c.codusur1 = u.codusur
    and c.codcli = f.codcli(+)
    and c.codcli = e.codcli(+)
    and c.codcli = o.codcli(+)
    and c.codcli = i.codcli(+)
    and i.codatv1 = a.codativ(+)
    and (c.observacao_pc like '%INBOUND%'
            or (c.observacao_pc like '%OUTBOUND%' 
                or (c.observacao_pc like '%SITE%'
                    or (c.observacao_pc like '%FACEBOOK%'
                        or (c.observacao_pc like '%LINKEDIN%'
                            or (c.observacao_pc like '%WHATSAPP%'
                                or (c.observacao_pc like '%CHAT%'      
                                   )   
                               ) 
                           )  
                       )  
                   )
               )
        ) 
        
group by 
    c.cgcent, 
    c.codcli, 
    c.cliente, 
    c.telent, 
    c.codusur1, 
    u.nome, 
    c.email, 
    c.observacao_pc, 
    decode(c.obs, 'A','Aprovado','P','Pendente'), 
    c.dtinclusao, 
    c.dtalteracao, 
    i.dtprimcompra, 
    i.dtultcomp, 
    i.codatv1, 
    a.ramo  

order by
    c.dtinclusao
   
--  '%INBOUND%'
--  '%OUTBOUND%' 
--  '%SITE%'
--  '%FACEBOOK%'
--  '%LINKEDIN%'
--  '%WHATSAPP%'
--  '%CHAT%'
Vou testar assim.
Essa função analítica, usei para outra consulta aqui, aonde precisava sequenciar e contar por vendas X praça X vendedor.
Caiu como uma luva! valeu pela dica!
Responder
  • Informação
  • Quem está online

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