database - ISO-8601 in Postgres: How to insert only year in type date? (incomplete date-time values) -
the postgres database claims supports iso-8601 standard. in iso-8601 date format "yyyy", i.e. consisting of year, fine , acceptable. can't find way add year postgres database field of type "date". idea if i'm doing wrong or feature missing in postgres?
i've seen other posts advising set date "yyyy-01-01" not want , need (since marks specific day of month of year).
scenario
the scenario following. collecting information on people. many have exact dates. have no dates or years, or year , month no day. have able find people born before year, or after other year. easy if have full date. hoped there feature implemented in postgres handle cases of incomplete dates.
to year of date
data type:
select extract(year '2014-01-01'::date) the_year; the_year ---------- 2014
if need year use smallint check constraint
create table t ( the_year smallint check( the_year between 0 , extract(year current_date) ) ); insert t (the_year) values (2030); error: new row relation "t" violates check constraint "t_the_year_check" detail: failing row contains (2030). insert t (the_year) values (2014); insert 0 1
but if store whole date makes no sense separate 3 columns.
note semantics of column application. if column of date
type application considers year column means year.
check date/time functions , operators
one solution partial date problem pointed @a_horse in comments create column indicating precision of date
create table t ( the_date date, the_date_precision varchar(5) ); insert t (the_date, the_date_precision) values (current_date, 'year'), (current_date, 'month'), (current_date, 'day') ; select case the_date_precision when 'year' to_char(the_date, 'yyyy') when 'month' to_char(the_date, 'yyyy-mm') else to_char(the_date, 'yyyy-mm-dd') end the_date t ; the_date ------------ 2014 2014-02 2014-02-06
the above kiss aproach think next implementation more elegant
create table t ( the_date date, the_date_precision smallint ); insert t (the_date, the_date_precision) values (current_date, 1), (current_date, 2), (current_date, 3) ; select array_to_string( ( string_to_array(to_char(the_date, 'yyyy-mm-dd'), '-') )[1:the_date_precision] , '-' ) the_date t ; the_date ------------ 2014 2014-02 2014-02-06
that select expression turned function easier reproduce. or view
create view view_t select *, array_to_string( ( string_to_array(to_char(the_date, 'yyyy-mm-dd'), '-') )[1:the_date_precision] , '-' ) the_date_output t ; select * view_t; the_date | the_date_precision | the_date_output ------------+--------------------+----------------- 2014-02-06 | 1 | 2014 2014-02-06 | 2 | 2014-02 2014-02-06 | 3 | 2014-02-06
Comments
Post a Comment