sql >> Databáze >  >> RDS >> PostgreSQL

Postgresql odstraní více řádků z více tabulek

Uspořádání řádných kaskádových mazání je moudré a obvykle je to správné řešení. Pro určité speciální případy existuje jiné řešení, které může být relevantní.

Pokud potřebujete provést více odstranění na základě společné sady dat, můžete použít Common Table Expressions (CTE) .

Je těžké přijít s jednoduchým příkladem, protože hlavní případ použití může být pokryt kaskádovým mazáním.

V příkladu smažeme všechny položky v tabulce A, jejichž hodnota je v sadě hodnot, které odstraňujeme z tabulky B. Obvykle by to byly klíče, ale tam, kde nejsou, nelze použít kaskádové mazání. .

Chcete-li to vyřešit, použijte CTEs

WITH Bdeletes AS (
    DELETE from B where IsSomethingToDelete = true returning ValueThatRelatesToA
)
delete from A where RelatedValue in (select ValueThatRelatesToA from Bdeletes)

Tento příklad je záměrně jednoduchý, protože mým cílem není dohadovat se o mapování klíčů atd., ale ukázat, jak lze provést dvě nebo více smazání ze sdílené datové sady. To může být také mnohem složitější, včetně příkazů pro aktualizaci atd.

Zde je složitější příklad (z osobní databáze Dartha Vadera). V tomto případě máme tabulku, která odkazuje na tabulku adres. Musíme odstranit adresy z tabulky adres, pokud jsou v jeho seznamu planet, které zničil. Chceme tyto informace použít k odstranění z tabulky lidí, ale pouze pokud byli na planetě (nebo na jeho seznamu zabitých trofejí)

with AddressesToDelete as (
    select AddressId from Addresses a 
    join PlanetsDestroyed pd on pd.PlanetName = a.PlanetName
),
PeopleDeleted as (
    delete from People 
    where AddressId in (select * from AddressesToDelete)
    and OffPlanet = false 
    and TrophyKill = false
    returning Id
),
PeopleMissed as (
    update People 
    set AddressId=null, dead=(OffPlanet=false)
    where AddressId in (select * from AddressesToDelete)
    returning id
)
Delete from Addresses where AddressId in (select * from AddressesToDelete)

Nyní je jeho databáze aktuální. Žádné selhání integrity kvůli smazání adresy. Všimněte si, že i když vracíme data z aktualizace a prvního smazání, neznamená to, že je musíme použít. Nejsem si jistý, zda můžete vložit smazání do CTE bez vrácených dat (Můj SQL může být také nesprávný při použití návratu z aktualizace - nemohl jsem to otestovat, protože Darth V. byl v výstřední nálada.



  1. problém se spuštěním liquibase s maven a postgres-db

  2. Top 3 tipy, které potřebujete vědět, abyste mohli psát rychlejší SQL pohledy

  3. Najděte všechny nečíselné hodnoty ve sloupci v MariaDB

  4. Jak dynamicky pivotovat s datem jako sloupcem