4

I have a table where I have multiple integer columns: year, month and day. Unfortunately, while the three should have been grouped into one DATE column from the beginning, I am now stuck and now need to view it as such. Is there a function that can do something along the lines of:

SELECT makedate(year, month, day), othercolumn FROM tablename;

or

SELECT maketimestamp(year, month, day, 0, 0), othercolumn FROM tablename;
4
  • Out of interest, what DB are you used to having makedate and maketimestamp in? Docs links? I'd like to make sure the PostgreSQL versions are consistent. Commented Jul 17, 2013 at 2:44
  • I was not thinking of any specific DB. But I think MySQL has something similar to makedate (though it doesn't use months). Commented Jul 17, 2013 at 7:29
  • It does, but it takes a year and day of year according to the manual. It looks like MySQL doesn't have anything exactly like you describe either. Commented Jul 17, 2013 at 7:32
  • Yes, that's what I meant. In either case, I find it somewhat odd that these functions are not included. Commented Jul 17, 2013 at 10:10

4 Answers 4

11

You can

SELECT format('%s-%s-%s', "year", "month", "day")::date
FROM ...

or use date maths:

SELECT DATE '0001-01-01'
    + ("year"-1) * INTERVAL '1' YEAR
    + ("month"-1) * INTERVAL '1' MONTH
    + ("day"-1) * INTERVAL '1' DAY
FROM ...

Frankly, it's surprising that PostgreSQL doesn't offer a date-constructor like you describe. It's something I should think about writing a patch for.

In fact, a quick look at the sources shows that there's an int date2j(int y, int m, int d) function at the C level already, in src/backend/utils/adt/datetime.c. It just needs to be exposed at the SQL level with a wrapper to convert to a Datum.

OK, now here's a simple makedate extension that adds a single function implemented in C, named makedate. A pure-SQL version is also provided if you don't want to compile and install an extension. I'll submit the C function for the 9.4 commitfest; meanwhile that extension can be installed to provide a fast and simple date constructor:

regress=# SELECT makedate(2012,01,01);
  makedate  
------------
 2012-01-01
(1 row)
Sign up to request clarification or add additional context in comments.

Comments

2

PostgreSQL 9.4+

In PostgreSQL 9.4, a function was added to do just this

Comments

1

There may be a more elegant method, but this will give you a date.

select to_date(to_char(year * 10000 + month * 100 + day,'00000000'), 'yyyymmdd')
from   tablename;

Comments

-1

Try something like:

SELECT year * interval '1 year' + 
       month * interval '1 month' + 
       day * interval '1 day'
FROM tablename;

1 Comment

I think you'd have to add that to a date to get a date-type result -- it gives an interval, I think.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.