Array
(
)

Query para trazer registros iguais na mesma tabela

Pjava
   - 15 dez 2011

Tenho uma tabela chamada indice com uma chave primária composta de tres campos:
cod_indice,cod_documento e indice. O que difere mesmo é o campo cod_documento. Eu preciso fazer um update, passando todos os cod_indice que tem valor 60 e 96 e passar para os que possuem o cod_indice 66. Acontece que dá erro de violação de chave, porque há registros que possam ter o mesmo cod_documento(nesse caso teria cod_indice diferentes). Então, preciso localizar esses registros para não incluir no meu Update. Como faço então para saber(na mesma tabela), quais registros tem o mesmo cod_documento, porem cod_indice diferentes. Como eu faço?

Bruno Manguinho
   - 15 dez 2011

#Código

UPDATE INDICE SET
	COD_INDICE = 66
WHERE COD_INDICE IN (60,96) AND
COD_DOCUMENTO NOT IN (SELECT COD_DOCUMENTO FROM INDICE WHERE COD_INDICE = 66)


Pelo que eu entendi ficaria assim seu código.

Utilizei uma subquerie para retornar todos os cod_documentos que possuam cod_indice = 66, com o NOT IN precedendo a subquerie elimina todos os cod_indice com valor 60 e 96 mas que tenham um cod_documento que ja existe para o cod_indice = 66.

Se não for exatamente isso, exemplifique mais.

Pjava
   - 19 dez 2011

Assim não funciona e vou explicar porque. A chave primária é composta de tres campos(Cod_Indice,cod_documento,num_indice). Nessa tabela existe ainda outro campo campo chamado valor. O que acontece, que eu posso ter um registro assim:

cod_indice cod_documento num_indice valor
-------------------------------------------------------------------------------------------
60 458971 0 Empresa de Engenharia caindo do prédio ltda
66 458971 0 OPDZ construções e empreendimento ltda

Veja que ao dar um update vai dar erro. Eu preciso é ignorar quando existe algo parecido. Existe 40 registros nessas condições e eles devem ser ignorados. É isso que não consigo fazer.

Pjava
   - 19 dez 2011

Fiz essa query e não deu certo

UPDATE
INDICE_STRING SET COD_INDICE = 66
WHERE
COD_DOCUMENTO IN(SELECT COD_DOCUMENTO
FROM
DOCUMENTO
WHERE
COD_TIPO_DOCUMENTO = 7950) AND COD_INDICE IN( 60,96,66 )
AND COD_DOCUMENTO NOT IN(SELECT COD_DOCUMENTO FROM INDICE_STRING
WHERE COD_INDICE IN(96,60)
GROUP BY COD_DOCUMENTO
HAVING COUNT(0) > 1);

Marco Pinheiro
   - 19 dez 2011

Se eu entendi seu problema, veja o codigo abaixo:

create table teste (cod_indice int, cod_doc int, indice int, constraint pkteste primary key (cod_indice, cod_doc, indice))

insert into teste values (60, 1, 0)
insert into teste values (66, 1, 0)
insert into teste values (96, 1, 0)
insert into teste values (60, 2, 0)
insert into teste values (66, 2, 0)
insert into teste values (96, 2, 0)
insert into teste values (60, 3, 0)

update teste
set cod_indice = 66
from (select a.cod_indice, a.cod_doc
from (select cod_indice, cod_doc from teste where cod_indice in (60,96)) a
left join
(select cod_indice, cod_doc from teste where cod_indice in (66)) b
on a.cod_doc = b.cod_doc
where b.cod_indice is null) temp

where teste.cod_doc = temp.cod_doc and
teste.cod_indice = temp.cod_indice

select * from teste

O único registro que foi alterado foi o (60, 3, 0), pois o cod_doc = 3 é o único que não existe vinculo com outro cod_indice = 60 ou 96

Att.,

Marco.

Bruno Manguinho
   - 13 jan 2012


Citação:
Assim não funciona e vou explicar porque. A chave primária é composta de tres campos(Cod_Indice,cod_documento,num_indice). Nessa tabela existe ainda outro campo campo chamado valor. O que acontece, que eu posso ter um registro assim:

cod_indice cod_documento num_indice valor
-------------------------------------------------------------------------------------------
60 458971 0 Empresa de Engenharia caindo do prédio ltda
66 458971 0 OPDZ construções e empreendimento ltda

Veja que ao dar um update vai dar erro. Eu preciso é ignorar quando existe algo parecido. Existe 40 registros nessas condições e eles devem ser ignorados. É isso que não consigo fazer.


Cara, mas é exatamente isso que o código faz:

UPDATE INDICE SET
COD_INDICE = 66
WHERE COD_INDICE IN (60,96) AND /* Seta todos os indices que tem valores 60 e 96 para 66 */
COD_DOCUMENTO NOT IN (SELECT COD_DOCUMENTO FROM INDICE WHERE COD_INDICE = 66) /* Exceto os indices 60 e 96 que possuam um cod_documento igual aos cod_documentos de cod_indicie 66

Você tentou rodar essa query?