sql >> Databasteknik >  >> RDS >> Mysql

Problem med att linda huvudet runt komplex SQL-raderingsfråga

Börja med att identifiera registreringarna för de andra kunderna av en registrering. Här är en vy:

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;

Det ger oss:

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         

Du behöver inte utsikt, naturligtvis; det är bara för bekvämligheten. Du kan bara använda ett virtuellt bord. Men inspektera det noggrant för att övertyga dig själv om att det ger rätt utbud av "pal-registreringar" för varje kund. Observera att vyn inte gör det referens Registration . Det är viktigt eftersom det ger samma resultat även efter att vi använder det för att radera från Registration , så vi kan använda den för det andra delete-satsen.

Nu har vi en lista över kunder och deras "pal-registreringar". Vilket är datumet för varje kompis senaste registrering?

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

Vilka har ett senaste datum före en viss tid?

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 som skulle innebära att klient #4 skulle raderas, och allt han registrerade sig för borde raderas. Registreringar skulle vara

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       

Och visst är klient #4 i registrering #5 och är den enda klienten som kan raderas genom detta test.

Därifrån kan du räkna ut delete uttalanden. Jag tror att regeln är "ta bort klienten och allt han registrerat sig för". Om så är fallet skulle jag förmodligen skriva registrerings-ID:n till en tillfällig tabell och skriva borttagningarna för båda Registration och AssociatedClient genom att ansluta sig till det.



  1. Förbättra SQL INSERT-frågan för att undvika sql-injektioner

  2. MySQL - Hur spårar man varje fråga?

  3. Varning för användaren/local/mysql/datakatalogen ägs inte av mysql-användaren

  4. PHP MySQL visar flera rader grupperade efter vanliga fält