Casting a string to Date and Time in PostgreSQL - postgresql

I have a table in GreenPlum (PostgreSQL) with all fields as sting, and I want to edit the types :
To do this I created a view :
CREATE VIEW typed_view AS
SELECT CAST(sid AS bigint), CAST(gid AS bigint),
...
But I have a problem with the Date and Time fields, I tried this command but it didn't work :
to_utc_timestamp(from_unixtime(unix_timestamp(eventdatetime,"yyyy-MM-dd
HH:mm:ss")),'UTC') AS eventdatetime,
After that I tried the PostgreSQL notation :
to_timestamp(eventdatetime, 'YYYY Mon DD HH24 MI SS') AS eventdatetime,
But still not working.
Anyone knows how to convert it ?
I also have this command that is not working :
CASE WHEN fix = "True" THEN TRUE ELSE FALSE END AS fix,
Thanks in advance

You didn't provide example data so I'm going to assume your data looks like "YYYY Mon DD HH24 MI SS". So January 4, 2016 at 2:15:20 PM would look like '2016 Jan 04 14 15 20' in your data. So with this example data, the conversion would look like this:
gpadmin=# select to_timestamp('2016 Jan 04 14 15 20', 'yyyy mon dd hh24 mi ss') as col1;
col1
------------------------
2016-01-04 14:15:20-05
(1 row)
Now this is a timestamp which also include the timezone offset which for my server is -5. To convert this to a timestamp without the timezone, you just add ::timestamptz.
gpadmin=# select to_timestamp('2016 Jan 04 14 15 20', 'yyyy mon dd hh24 mi ss')::timestamp as col1;
col1
---------------------
2016-01-04 14:15:20
(1 row)
A very important note on this. It is costly to convert data from a string to a different datatype. That is the same in all databases too. It is better to incur the expense of this conversion once rather than doing it for every SELECT statement. So, I also suggest you materialize this transformation into a physical table rather than using a VIEW.

Related

How to get large number in Amazon Redshift?

I am trying to get epochtime (13 digits) after subtracting from task_end_time column using something like
((task_end_time - to_date ('01 Jan 1970 00:00:00', 'DD Mon YYYY HH24:MI:SS')) * 24 * 3600* 1000)::bigint AS "log_datetime"
This gives me below exception
ERROR: XX000: Integer data overflow (multiplication)
seems like all you actually need to do is
extract('epoch' from task_end_time) AS "log_datetime"

Producing date from year and month values in PostgreSQL

Hello I'm having two problems with converting a concatenated date value into an actual date.
I've tired looking here to convert the concatenated value with to_char(DATE ...) but I keep getting odd dates. I think it is because my month does not have a zero padding in front of it.
This is my base query:
SELECT
expiry_month,
expiry_year,
to_date(CONCAT(expiry_year, expiry_month), 'YYYY/MM'),
FROM thisTable
Here is an example of the data output:
expiry_month expiry_year concatvalues
9 2018 20189-01-01
1 2019 20191-01-01
5 2016 20165-01-01
3 2019 20193-01-01
10 2017 201710-01-01
2 2020 20202-01-01
I think I need to LPAD() my month value to get the correct date parsed. E.g. 01 not 1, and 05 not 5.
However when I try to LPAD the month values it does not work. I've tried:
lpad(to_char(expiry_month),2,'0'),
I get this error 'HINT: No function matches the given name and argument types. You might need to add explicit type casts.'
Which I don't understand because lpad is a function. Any suggestion on how to use LPAD()?
Thank you for the advice.
EDIT 1
I've tried to update the to_date() function with this code:
to_date(CONCAT(payment_cards.expiry_year || ' - ' || payment_cards.expiry_month || ' - 01'), 'YYYY-MM-01') and now it is throwing a different error:
ERROR: invalid value "- " for "MM" DETAIL: Value must be an integer.
I'm still thinking I need to pad the month date?
There's a '/' missing:
SELECT
expiry_month,
expiry_year,
to_date(CONCAT(expiry_year, '/', expiry_month), 'YYYY/MM') AS the_start_of_year_month
FROM thisTable ;
will produce:
expiry_month | expiry_year | the_start_of_year_month
-----------: | ----------: | :----------------------
9 | 2018 | 2018-09-01
1 | 2019 | 2019-01-01
5 | 2016 | 2016-05-01
3 | 2019 | 2019-03-01
10 | 2017 | 2017-10-01
2 | 2020 | 2020-02-01
The date format is specifying '/' and it wasn't there, so, the whole text was taken as the year, and the month and day were taken as 1/1. CONCAT('2018','9') was just returning '20189' (which is a valid year).
dbfiddle here
Use:
make_date(year int, month int, day int)
like:
make_date(expiry_year, expiry_month, 1)
Postgresql documentation

RR MILLENNIUM equivalent in Postgres

Is there a built in function in PostgreSQL 9.5 version to calculate the appropriate century/millenium?
When I use birth_date::TIMESTAMP from a table, sometimes it prefix 19 and sometimes it prefix 20. Below example
Input:
28JUN80
25APR48
Output:
"1980-06-28 00:00:00"
"2048-04-25 00:00:00"
I also have records in the table with birth_date holding values like "07APR1963" which gets computed appropriately as "1963-04-07 00:00:00".
I need use CASE statement when the length is 7 characters, then prefix with 19 millennium and when its 9 characters, just load it as it is.
https://en.wikipedia.org/wiki/Unix_time Unix epoch is
beginning (00:00:00 1 January 1970)
So if you don't specify the century, but just last YY it will be 20th century from 00:00:00 1 January and 21st century before YY equal 70. If you want it to guess the 20th century either append year as you do, or specify CC, eg:
t=> select
to_timestamp('1JAN70', 'ddmonYY')
, to_timestamp('31DEC69', 'ddmonyy')
, to_timestamp('31DEC69 20', 'ddmonyy cc');
to_timestamp | to_timestamp | to_timestamp
------------------------+------------------------+------------------------
1970-01-01 00:00:00+00 | 2069-12-31 00:00:00+00 | 1969-12-31 00:00:00+00
(1 row)
https://www.postgresql.org/docs/current/static/functions-formatting.html
In conversions from string to timestamp or date, the CC (century)
field is ignored if there is a YYY, YYYY or Y,YYY field. If CC is used
with YY or Y then the year is computed as the year in the specified
century. If the century is specified but the year is not, the first
year of the century is assumed.
update
So in your case you should do smth like:
vao=# create table arasu (member_birth_date character(9)); insert into arasu values ('28JUN80'),('25APR48');
CREATE TABLE
INSERT 0 2
vao=# select to_timestamp(member_birth_date||' 20', 'ddmonYY cc') from arasu;
to_timestamp
------------------------
1980-06-28 00:00:00+03
1948-04-25 00:00:00+03
(2 rows)

Dateparse MON in Tableau

I have a data source that returns a date as a string in the form of 'MON YYYY' (APR 2014, MAY 2014, etc.).
I tried making a calculated field off of this information with the following formula:
DATEPARSE('MMM YYYY', [Field1])
This is a sample set of the data I'm getting (I added the pipe as a divider):
Field1 || Calculated Field
APR 2014 || 12/22/2013
APR 2015 || 12/28/2014
APR 2016 || 12/27/2015
AUG 2014 || 12/22/2013
AUG 2015 || 12/28/2014
AUG 2016 || 12/27/2015
I've also tried to add a day field, but that results in the same incorrect data as above:
DATE(DATEPARSE('dd MMM YYYY','01 ' +[Field1]))
Is there something I'm perhaps misunderstanding about the dateparse function?
It turns out that YYYY means something totally different than yyyy. The capitalized MMMwas necessary for the MON type description. This worked for me:
DATE(DATEPARSE('MMM yyyy',[Field1]))
If you date the date off you'll get the hour, minute, second fields as well.
Dateparse converted it from a string [Field1] into a Date type using the aforementioned format of three digit month, a space, and a four digit year (e.g. AUG 2014 -> 8/2/2014).

Can someone show me how I can output hrs:mins:secs in mySQL SELECT statement below?

Here is the picture of how I would like it to be displayed
Here is what I have so far when use the DATE_ADD function in MySQL Workbench 6.3, but I have been struggling to output the hrs:mins:secs (you don't see the code for that output because I didn't write it here). I know that I can use INTERVAL HOUR_SECOND to display hrs:mins:secs but I don't understand how it works.
SELECT DATE_ADD('2017-01-26', INTERVAL 31 DAY) AS '31 Days';
I know this SELECT statement above will output 31 days from the specified date indicated above, but what do I need to do to output the hrs:mins:secs along with the 31 days from the date in the SELECT statement?
You can do it using DATE_FORMAT(). Examples:
Add function
/*
* Adds a particular interval to given date
*/
SELECT DATE_ADD('2017-01-26', INTERVAL 31 DAY) AS '31 Days';
Output:
31 Days
2017-02-26
Format function
/*
* Formats a particular date object
*/
SELECT DATE_FORMAT(NOW(),'%b %d %Y %h:%i %p')
AS 'Now';
Output:
Now
Jan 28 2017 04:29 PM
Format and add:
/*
* Adds and Formats date object
*/
SELECT DATE_FORMAT(DATE_ADD('2017-01-26', INTERVAL 31 DAY),'%b %d %Y %h:%i %p')
AS 'Formatted date';
Output:
Formatted date
Feb 26 2017 12:00 AM
Additionally, here is the sqlfiddle for the example: http://sqlfiddle.com/#!9/9eecb7d/92948
Also check the various formats to further tailor to your needs: http://www.w3schools.com/sql/func_date_format.asp