Similaridades do produto

Auditorias para similaridades de produtos

PROD.SIMILARIDADES_PRODUTO.FAQ-143075
Para identificar problemas com a estrutura de similaridades do sistema, executar o script abaixo:

Script
select *
, case when numero > 0 then 'background-color:red; color:white; font-weight:bold' end as _MENSAGEM__STYLE
from (

select count(1) as numero
, 'Similaridades de marcas/referencias de produtos cadastrados' as mensagem
from similaridades_produto sp
join produtos p on p.marca_id = sp.marca_id and p.referencia_fabricante = sp.referencia
where sp.produto_similar_id is null

union

select count(1) as numero
, 'Similares sem o reverso' as mensagem
from similaridades_produto s1
left join similaridades_produto s2 on s2.produto_id = s1.produto_similar_id and s2.produto_similar_id = s1.produto_id
where s2.id is null
and s1.produto_similar_id is not null

union

select count(distinct p1.id) as numero
, 'Pares de produtos com o mesmo grupo similar mas que não tem relacionamento entre si' as mensagem
from produtos p1
join produtos p2 on p2.grupo_similar_id = p1.grupo_similar_id and p1.id <> p2.id
left join similaridades_produto s on s.produto_id = p1.id and s.produto_similar_id = p2.id
where s.id is null

union

select count(1) as numero
, 'Grupos similares conflitantes' as mensagem
from similaridades_produto s
join produtos p1 on p1.id = s.produto_id
join produtos p2 on p2.id = s.produto_similar_id
where p1.grupo_similar_id <> p2.grupo_similar_id

union

select count(distinct p.grupo_similar_id) as numero
, 'Grupos similares que não tem nenhum relacionamento' as mensagem
from produtos p
where not exists (
 select 1
 from similaridades_produto s
 join produtos p1 on p1.id = s.produto_id
 and p1.grupo_similar_id = p.grupo_similar_id
)

) q
order by mensagem

Correções

As correções a seguir devem ser aplicadas apenas após avaliação das causas.

Grupos similares conflitantes

Caso não sejam muitos registros, o melhor é remover essas similaridades.
delete from similaridades_produto
where id in (
    select s.id as similaridades_conflitando_grupo
    from similaridades_produto s
    join produtos p1 on p1.id = s.produto_id
    join produtos p2 on p2.id = s.produto_similar_id
    where p1.grupo_similar_id <> p2.grupo_similar_id);


Grupos similares sem nenhum registro de similaridade

update produtos p
set grupo_similar_id = null
where not exists (
    select 1
    from similaridades_produto s
    join produtos p1 on p1.id = s.produto_id
    and p1.grupo_similar_id = p.grupo_similar_id
)
and grupo_similar_id is not null


Similaridades sem reverso

Estes casos podem ser aplicados sem maiores problemas desde que similaridades conflitantes tenham sido resolvidas.
insert into similaridades_produto (id,produto_id,marca_id,produto_similar_id,referencia)
select s1.produto_similar_id
, s1.produto_similar_id
, s1.marca_id
, s1.produto_id 
, s1.referencia
from similaridades_produto s1
left join similaridades_produto s2 on s2.produto_id = s1.produto_similar_id and s2.produto_similar_id = s1.produto_id
where s2.id is null
and s1.produto_similar_id is not null

Similaridades de marcas/referencias de produtos cadastrados

Configurar preferência:
PROD.SIMILARIDADES_PRODUTO.VALIDACAO_DUPLICIDADE = N

Reconstrução dos grupos similares

O script abaixo reconstrói os grupos similares e pode ser utilizado nos casos onde estas informações estiverem muito inconsistentes.
update produtos set grupo_similar_id = null;

UPDATE produtos
SET grupo_similar_id = least(id, q.grupo_similar_id)
FROM (
   SELECT produto_id, min(produto_similar_id) as grupo_similar_id
   from similaridades_produto 
   group by produto_id
) AS q
WHERE id = q.produto_id

Remover duplicidades

delete from similaridades_produto
where id in (
   select greatest(s1.id, s2.id) as id
   from similaridades_produto s1
   join similaridades_produto s2 on s1.produto_id = s2.produto_id and s1.produto_similar_id = s2.produto_similar_id and s1.id <> s2.id
   where s1.produto_similar_id is not null
)