sql >> Database >  >> RDS >> PostgreSQL

Niet-aaneengesloten perioden markeren

generate_series()

PostgreSQL's generate_series() functie kan een weergave maken die een opeenvolgende lijst met datums bevat:

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;

De uitdrukking select max(date) - min(date) from test zit er misschien één naast.

Tel dagen per maand

Een manier om ongeldige maanden te identificeren, is door twee weergaven te maken. De eerste telt het aantal dagelijkse metingen dat elk station in elke maand moet produceren. (Merk op dat climate.calendar is vertaald naar climate_calendar .) De tweede retourneert de werkelijke dagelijkse metingen die elk station per maand heeft geproduceerd.

Maximum aantal dagen per maand per station

Deze weergave retourneert het werkelijke aantal dagen in een maand, per station. (Februari heeft bijvoorbeeld altijd 28 of 29 dagen.)

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

Werkelijke dagen per maand per station

Het totale aantal geretourneerde dagen zal minder zijn dan de aantallen. (Januari heeft bijvoorbeeld altijd 31 dagen of minder.)

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;

Laat de ORDER BY vallen clausules in productie (ze zijn nuttig bij de ontwikkeling).

Beelden vergelijken

Voeg de twee weergaven samen om de stations en maanden te identificeren die moeten worden gemarkeerd, in een nieuwe weergave:

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

De kolom num_days_missing is niet nodig, maar het is wel handig.

Dit zijn de rijen die moeten worden bijgewerkt:

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

Database bijwerken

Om ze bij te werken, de id sleutel is handig.

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. krijg afbeeldingen van mysql met php jquery ajax en toon ze in html-pagina in DIV's

  2. kolom bestaat niet, zelfs niet bij gebruik van het trefwoord 'as'

  3. RoR Postgresql-tijdzonegroep door niet te werken aan Heroku

  4. Hoe u Change Data Capture (CDC) op de hele tabel inschakelt OF CDC op tabel inschakelt met lijst met kolommen in SQL Server