Mysql
 sql >> Database >  >> RDS >> Mysql

Problemi a capovolgere la complessa query di eliminazione SQL

Inizia identificando le registrazioni degli altri clienti di una registrazione. Ecco 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;

Questo ci dà:

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         

Non hai bisogno di una vista, ovviamente; è solo per comodità. Potresti semplicemente usare un tavolo virtuale. Ma ispezionalo attentamente per convincerti che produce la giusta gamma di "registrazioni amici" per ogni cliente. Nota che la vista non riferimento Registration . Questo è significativo perché produce gli stessi risultati anche dopo che lo usiamo per eliminare da Registration , quindi possiamo usarlo per la seconda istruzione delete.

Ora abbiamo un elenco di clienti e le loro "registrazioni amici". Qual è la data dell'ultima registrazione di ogni amico?

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

Quali hanno un'ultima data prima di un tempo certo?

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 ciò significherebbe che il client n. 4 dovrebbe essere eliminato e tutto ciò per cui si è registrato dovrebbe essere eliminato. Le registrazioni sarebbero

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       

E, abbastanza sicuro, il client n. 4 è nella registrazione n. 5 ed è l'unico client soggetto a cancellazione da parte di questo test.

Da lì puoi elaborare il delete dichiarazioni. Penso che la regola sia "eliminare il cliente e tutto ciò per cui si è registrato". In tal caso, probabilmente scriverei gli ID di registrazione in una tabella temporanea e scriverei le eliminazioni per entrambe le Registration e AssociatedClient unendosi ad esso.