Update com subquery

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
IgorVerta
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 7
Registrado em: Qui, 13 Jan 2011 4:19 pm
Localização: RJ
Igor Verta
RJ
Niterói

Fala pessoal boa tarde...
Estou tentando fazer um update com um subquery... no entanto estou recebndo o seguinte erro :

Selecionar tudo

ORA-01427 single-row subquery returns more than one row...
Sei que na minha tabela emp_fv existe linhas duplicadas mas é para atualizar todas mesmo... mas acreditava que dando o group by acabaria com as duplicidades da tabela f_99 ...
Se puderem me ajudar agradeço :)

Segue a query :

Selecionar tudo

update emp_fv e set CODIGO_PDV_HUNTER = ( select f.cod_sap from    
                                           emp_fv e, f_99 f
                                          where e.cpf_cnpj = f.cnpj
                                          and e.uf = f.filial
                                          and desc_canal like 'HUNTER' 
                                          group by cod_sap)
Abs
gfkauer
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 389
Registrado em: Ter, 27 Jul 2010 1:34 pm
Localização: Sapiranga - RS
Contato:
Quem falou que programar era fácil??

Quanto mais dificil for a implementação mais valorizado seu trabalho será!

Acessem: www.gfkauer.com.br

Teste Isto:

Selecionar tudo

Update emp_fv e
   Set codigo_pdv_hunter =
       (Select f.cod_sap
          From f_99   f
         Where e.cpf_cnpj = f.cnpj
           And e.uf = f.filial
           And desc_canal Like 'HUNTER'
         Group By cod_sap)
burga
Rank: DBA Pleno
Rank: DBA Pleno
Mensagens: 232
Registrado em: Qui, 26 Nov 2009 1:05 pm
Localização: SP
Ricardo H. Tajiri

mas acreditava que dando o group by acabaria com as duplicidades da tabela f_99 ...
Não elimina as duplicadas pois, pelo jeito, existem mais de um cod_sap diferente pras condições

Selecionar tudo

e.cpf_cnpj = f.cnpj and e.uf = f.filial and desc_canal like 'HUNTER'
Neste caso você tem que optar por apenas um dos dois (ou mais) cod_sap's retornados pra preencher a coluna CODIGO_PDV_HUNTER.

Como fazer isso?

Primeiro, como eu já disse antes, você deve escolher qual dos cod_saps retornados irá ser usado pra preencher as colunas. Feito isto você tenta retorná-lo usando, além das conduções que você á colocou, um

Selecionar tudo

ROWNUM = 1
(e um ORDER BY, se necessário).
IgorVerta
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 7
Registrado em: Qui, 13 Jan 2011 4:19 pm
Localização: RJ
Igor Verta
RJ
Niterói

GfKauer
Tentei e permaneceu o mesmo erro...
Mas de qualquer forma obrigado...

Burga obrigado pela explicação estou criando novas opções
Se existem duplicações de acordo com clausulas de igualdade... utilizando o raciocinio um pouco mais lógico se eu agrupar todos os termos que poderiam conter duplicidade e depois separa somente o campo que preciso... mataria de fato a duplicidade dos campos ...
Estou no raciocinio correto ?

Abs e obrigado
IgorVerta
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 7
Registrado em: Qui, 13 Jan 2011 4:19 pm
Localização: RJ
Igor Verta
RJ
Niterói

Ah e apenas acrecentando...
´
Eu preciso atualizar todos os campos da tabela emp_fv
com os dados do campo cod_sap vindo da tabela f_99 com as seguintes clausulas :

[code]e.cpf_cnpj = f.cnpj
e.uf = f.filial
desc_canal like 'HUNTER' [/code]

Abs
gfkauer
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 389
Registrado em: Ter, 27 Jul 2010 1:34 pm
Localização: Sapiranga - RS
Contato:
Quem falou que programar era fácil??

Quanto mais dificil for a implementação mais valorizado seu trabalho será!

Acessem: www.gfkauer.com.br

Pelo que notei o problema é o seguinte,

1 registro na tabela emp_fv contem diversos registros na tabela f_99 que respeita os filtros

Selecionar tudo

e.cpf_cnpj = f.cnpj
e.uf = f.filial
desc_canal like 'HUNTER' 
Desta forma o que você esta tentando fazer é atualizar 1 registro emp_fv varias vezes... por isto o sql não aceita...
marcus.kobel
Rank: Programador Sênior
Rank: Programador Sênior
Mensagens: 45
Registrado em: Qui, 12 Mai 2011 4:54 pm
Localização: Porto Alegre - RS

Só um comentário, Igor.
O fato de tu estar usando GROUP BY em uma query, não garante que ela vai retornar apenas um registro. Só quer dizer que os registros serão agrupado pra fazer COUNTs, SUMs, etc.... mas não quer dizer. Ele pode te retornar 1000 registos.
IgorVerta
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 7
Registrado em: Qui, 13 Jan 2011 4:19 pm
Localização: RJ
Igor Verta
RJ
Niterói

GfKauer

Na verdade o problema parece ser de relacionamento sim... eu tenho diversos registros de chave (cpf_cnpj) na tabela emp_fv e somente 1 registro na tabela f_99 que atenda as clausulas where...
O relacionamento é n:1

Pensei em remontar a querie utilizando algum join... Será que daria certo ?

Marcus

Compreendo que ira retornar diversos resultados... mas no caso de duplicidade o group by resolveria... essa e a questao... group by mata ou não a duplicidade de linhas numa query...

Obrigado
burga
Rank: DBA Pleno
Rank: DBA Pleno
Mensagens: 232
Registrado em: Qui, 26 Nov 2009 1:05 pm
Localização: SP
Ricardo H. Tajiri

No caso de duplicidade o group by mata sim, mas somente se todas as clnas do grup by tiverem os mesmos valores, assim como um distinct tamém o faria.

Mas o seu problema é que justamente a coluna que está no group by é que tem valores diferentes pras condições que você colocou, ou seja, a coluna cod_sap não está duplicada, apesar do cnpj, filal e canal estarem... Assim ele retorna mais do que um valor na sua subconsulta, pois existem mais de um cod_sap distinto pros mesmos valores de cnpj, filial e canal...

Por isto no meu primeiro post eu disse que você deve optar por qual dos valres usar e depois filtras com rownum = 1 com ou sem ORDER BY... Ou também pode usar o MIN, MAX, etc...
IgorVerta
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 7
Registrado em: Qui, 13 Jan 2011 4:19 pm
Localização: RJ
Igor Verta
RJ
Niterói

Valeu Burga agora entendi legal o que você queria dizer...
Mas antes de entender isso ontem mesmo fiz a seguinte query :

Selecionar tudo

update emp_fv e set CODIGO_PDV_HUNTER =   (select cod_sap from
                                          (
                                          select * from 
                                          ( select
                                          f.cnpj, f.cod_sap, f.filial, e.cpf_cnpj, e.uf, f.desc_canal
                                          from emp_fv e, f_99 f
                                          where e.cpf_cnpj = f.cnpj
                                          and e.uf = f.filial
                                          and desc_canal like 'HUNTER' 
                                          group by f.cnpj, f.cod_sap, f.filial,e.cpf_cnpj,e.uf, f.desc_canal,f.cnpj
                                          ) a
                                          )b
                                          where b.cnpj = e.cpf_cnpj)
Acho que agora vai... pois to agrupando as linhas que tão duplicadas.. ai agrupei tudo e selecionei só o que eu preciso fora... agrupando primeiro selecionando depois...
Acho que agora vai...até agora ta rodando mas se não funcionar.... vou atacar o problema de acordo com a tua dica ai burga...

Abs
IgorVerta
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 7
Registrado em: Qui, 13 Jan 2011 4:19 pm
Localização: RJ
Igor Verta
RJ
Niterói

Fala pessoal...
Boas noticias consegui resolver o problema... E dando sequência a solução do problema para ajudar a tirar duvidas como as minhas...
Segue a query salvadora abaixo com explicação ...

Selecionar tudo

update emp_fv e 
   set e.CODIGO_PDV_HUNTER = (select cod_sap from up_fv_hunter b /* tabela criada a partir do codigo de cruzamento para melhorar o tempo de execução */
                              where b.cnpj = e.cpf_cnpj
                              and e.codigo_pdv_hunter is null
                              AND ROWNUM < 2
                              group by cod_sap
                               )  
O salvador foi o Rownum que fez com que a query não considerasse as linhas duplicadas... que travavam o set.

Abs
Responder
  • Informação
  • Quem está online

    Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante