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

Označte nesouvislá období

generate_series()

generate_series() PostgreSQL může vytvořit pohled, který obsahuje po sobě jdoucí seznam dat:

with calendar as (
    select ((select min(date) from test)::date + (n || ' days')::interval)::date cal_date
    from generate_series(0, (select max(date) - min(date) from test)) n
)
select cal_date
from calendar c
left join test t on t.date = c.cal_date
where t.date is null;

Výraz select max(date) - min(date) from test může být o jednu mimo.

Počítat dny v měsíci

Jedním ze způsobů, jak identifikovat neplatné měsíce, je vytvořit dva pohledy. První počítá počet denních odečtů, které by každá stanice měla produkovat v každém měsíci. (Všimněte si, že climate.calendar je přeložen do climate_calendar .) Druhá vrací skutečné denní odečty každé stanice vyrobené za měsíc.

Maximální počet dní v měsíci na stanici

Toto zobrazení vrátí skutečný počet dní v měsíci na stanici. (Například únor bude mít vždy 28 nebo 29 dní.)

create view count_max_station_calendar_days as 
with calendar as (
    select ((select min(d) from climate_calendar)::date + (n || ' days')::interval)::date cal_date
    from generate_series(0, (select max(d) - min(d) from climate_calendar)) n
)
select n, extract(year from cal_date) yr, extract(month from cal_date) mo, count(*) num_days
from stations cross join calendar
group by n, yr, mo
order by n, yr, mo

Skutečné dny v měsíci na stanici

Celkový počet vrácených dní bude menší než součet. (Například leden bude mít vždy 31 dní nebo méně.)

create view count_actual_station_calendar_days as
select n, extract(year from d) yr, extract(month from d) mo, count(*) num_days
from climate_calendar
group by n, yr, mo
order by n, yr, mo;

Přetáhněte ORDER BY klauzule ve výrobě (jsou užitečné při vývoji).

Porovnat zobrazení

Spojte dva pohledy a identifikujte stanice a měsíce, které je třeba označit, do nového pohledu:

create view invalid_station_months as 
select m.n, m.yr, m.mo, m.num_days - a.num_days num_days_missing
from count_max_station_calendar_days m
inner join count_actual_station_calendar_days a
       on (m.n = a.n and m.yr = a.yr and m.mo = a.mo and m.num_days <> a.num_days)

n   yr    mo  num_days_missing
--
A   1982  1   1
E   2007  3   1

Sloupec num_days_missing není nutné, ale je užitečné.

Toto jsou řádky, které je třeba aktualizovat:

select cc.* 
from climate_calendar cc
inner join invalid_station_months im 
        on (cc.n = im.n and 
            extract(year from cc.d) = im.yr and
            extract(month from cc.d) = im.mo)
where valid = true

Aktualizovat databázi

Chcete-li je aktualizovat, id klíč je pohodlný.

update climate_calendar
set valid = false
where id in (
    select id
    from climate_calendar cc
    inner join invalid_station_months im 
        on (cc.n = im.n and 
            extract(year from cc.d) = im.yr and
            extract(month from cc.d) = im.mo)
    where valid = true
);


  1. MySQL – NEJMENŠÍ a NEJVĚTŠÍ srovnávací operátory

  2. Vztah „mnoho do dvou“.

  3. Správa a automatizace PostgreSQL s ClusterControl

  4. Parametr data aplikace Excel v dotazu SQL