sql >> Base de Datos >  >> RDS >> Mysql

Problemas para envolver la cabeza en una consulta compleja de eliminación de SQL

Comience identificando los registros de los otros clientes de un registro. Aquí hay una vista:

create view groups as 
select   a.Client_id
       , c.Registration_id
from AssociatedClient as a 
join AssociatedClient as b on a.Registration_id = b.Registration_id 
join AssociatedClient as c on b.Client_id = c.Client_id;

Eso nos da:

select Client_id
    , min(Registration_id) as first
    , max(Registration_id) as last
    , count(distinct Registration_id) as regs
    , count(*) as pals
from  groups 
group by Client_id;
Client_id   first       last        regs        pals      
----------  ----------  ----------  ----------  ----------
2           2           8           4           5         
3           2           8           4           18        
4           5           5           1           1         
5           2           8           4           5         
7           10          10          1           1         
8           9           9           1           1         

No necesitas una vista, por supuesto; es solo por conveniencia. Podrías simplemente usar una mesa virtual. Pero examínelo cuidadosamente para convencerse de que produce el rango correcto de "registros de amigos" para cada cliente. Tenga en cuenta que la vista no referencia Registration . Eso es significativo porque produce los mismos resultados incluso después de que lo usamos para eliminar de Registration , por lo que podemos usarlo para la segunda declaración de eliminación.

Ahora tenemos una lista de clientes y sus "registros de amigos". ¿Cuál es la fecha del último registro de cada amigo?

select g.Client_id, max(Registration_date) as last_reg
from groups as g join Registration as r
on g.Registration_id = r.Id
group by g.Client_id;
g.Client_id  last_reg  
-----------  ----------
2            2011-10-14
3            2011-10-14
4            2011-10-07
5            2011-10-14
7            2011-10-17
8            2011-10-14

¿Cuáles tienen una fecha más tardía antes de un tiempo determinado?

select g.Client_id, max(Registration_date) as last_reg
from groups as g join Registration as r
on g.Registration_id = r.Id
group by g.Client_id
having max(Registration_date) < '2011-10-08';
g.Client_id  last_reg  
-----------  ----------
4            2011-10-07

IIUC eso significaría que el cliente # 4 debe eliminarse, y todo lo que se registró debe eliminarse. Las inscripciones serían

select * from Registration
where Id in (
      select Registration_id from groups as g
      where Client_id in ( 
            select g.Client_id
            from groups as g join Registration as r
            on g.Registration_id = r.Id
            group by g.Client_id
            having max(Registration_date) < '2011-10-08'
      )
);
Id          Registration_date
----------  -----------------
5           2011-10-07       

Y, por supuesto, el cliente n.º 4 está en el registro n.º 5 y es el único cliente sujeto a eliminación por esta prueba.

A partir de ahí, puede resolver el delete declaraciones. Creo que la regla es "eliminar el cliente y cualquier cosa para la que se haya registrado". Si es así, probablemente escribiría los ID de registro en una tabla temporal y escribiría las eliminaciones para ambos Registration y AssociatedClient uniéndose a él.