creating a date from an existing one in HiveQL - date

I'm completely new to Hive and I would really appreciate some help.
I have a date column in my table and I would like to keep month and year of this date. What I would do in excel is the following:
datenew= date(year(old_date),month(old_date),1)
my old_date is in YYYY-MM-DD format.
Thanks!!

You can use trunc with mm option (for Hive versions 1.2 and later), which will return the first of a month.
trunc(dateCol,'MM')
If trunc is not supported, use
date_add(dateCol,1-day(dateCol))

You can use TRUNC (date,fmt) which is a function returns date with the time portion of the day truncated to the unit specified by the format model fmt. it always return a value of datatype DATE,:
Example:
hive> select trunc(current_date, 'MM');
OK
2018-05-01
hive> select trunc(current_date, 'YEAR');
OK
2018-01-01

Use date_format or trunc function, or substr()+concat().
Demo:
hive> select current_date original_date,
> date_format(current_date,'yyyy-MM-01') `date_format`,
> trunc(current_date, 'MM') `trunc`,
> concat(substr(current_date,1,7),'-01') `substr`
> ;
OK
original_date date_format trunc substr
2018-05-30 2018-05-01 2018-05-01 2018-05-01
Time taken: 0.093 seconds, Fetched: 1 row(s)

Related

Number of days in a month in DB2

Is there a way to find the number of days in a month in DB2. For example I have a datetime field which I display as Jan-2020, Feb-2020 and so on. Based on this field I need to fetch the number of days for that month. The output should be something like below table,
I'm using the below query
select reportdate, TO_CHAR(reportdate, 'Mon-YYYY') as textmonth from mytable
Expected output
ReportDate textMonth No of Days
1-1-2020 08:00 Jan-2020 31
1-2-2020 09:00 Feb-2020 29
12-03-2020 07:00 Mar-2020 31
Try this:
/*
WITH MYTABLE (reportdate) AS
(
VALUES
TIMESTAMP('2020-01-01 08:00:00')
, TIMESTAMP('2020-02-01 09:00:00')
, TIMESTAMP('2020-03-12 07:00:00')
)
*/
SELECT reportdate, textMonth, DAYS(D + 1 MONTH) - DAYS(D) AS NO_OF_DAYS
FROM
(
SELECT
reportdate, TO_CHAR(reportdate, 'Mon-YYYY') textMonth
, DATE(TO_DATE('01-' || TO_CHAR(reportdate, 'Mon-YYYY'), 'dd-Mon-yyyy')) D
FROM MYTABLE
);
Db2 has the function DAYS_TO_END_OF_MONTH and several others which you could use. Based on your month input, construct the first day of the month. This should be something like 2020-01-01 for Jan-2020 or 2020-02-01 for Feb-2020. Follow the link for several other conversion functions which allow you to transform between formats and to perform date arithmetics.
convert your column to a proper date and try this: day(last_day(date_column))

PostgreSQL group timestamp by date and truncate time

The table schema is like this:
Column | Type | Modifiers
--------+--------------------------+--------------------------------------------------
time | timestamp with time zone | default now()
The time format is like this:
time
------------------------
2016-07-11 18:58:28+00
2016-07-11 18:58:37+00
2016-07-12 00:59:31+00
How to group by date with time truncated?
I would like to see the result as:
date
------------------------
2016-07-11
2016-07-11
2016-07-12
If you want compare or group by dates instead of timestamps you can cast to DATE:
SELECT time::DATE, ... FROM ... GROUP BY time::DATE;
or simpler
SELECT time::DATE, ... FROM ... GROUP BY 1;
Take a look at the current Postgresql documentation for datetime functions: https://www.postgresql.org/docs/current/static/functions-datetime.html
You can use date_trunc, extract, to_char or the simplest way is to cast to date (as I would do):
SELECT time::date; // 2016-07-11 18:58:28+00 -> 2016-07-11
Cheers!
use date_trunc:
select date_trunc('day', time)

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)

Convert Period in Year/Quarter format to Date (First Day of Quarter)

I would like to take a string in the format 'YYYYQQ' and parse it into a date. Specifically I would like to parse it into the first date of the quarter. For example I would like to parse '2016Q2' into '2016-04-01'.
Per the Postgres documentation, "Q (quarter) is ignored by to_date and to_timestamp". Well frankly I wish it wasn't ignored :) This means this code will return a result I don't want:
select to_date('2014q3', 'YYYY\qQ');
**result**
2014-01-01
**desired result**
2014-07-01
How could I parse this string to the proper date?
Use string manipulation functions format(), left() and right():
with quarters(q) as (
values ('2014q1'), ('2015q2'), ('2016q3'), ('2017q4')
)
select format('%s-%s-1', left(q, 4), right(q, 1)::int* 3- 2)::date
from quarters;
format
------------
2014-01-01
2015-04-01
2016-07-01
2017-10-01
(4 rows)
Create a function for convenience:
create or replace function quarter_to_date(text)
returns date language sql as $$
select format('%s-%s-1', left($1, 4), right($1, 1)::int* 3- 2)::date
$$;
with quarters(q) as (
values ('2014q1'), ('2015q2'), ('2016q3'), ('2017q4')
)
select quarter_to_date(q)
from quarters;
quarter_to_date
-----------------
2014-01-01
2015-04-01
2016-07-01
2017-10-01
(4 rows)
In PostgreSQL 9.4 and greater there is a function that will create a date.
make_date(year, month, day)
You can use it as follows:
make_date(year, quarter * 3 -2 , 1)::date

PostgreSQL difference between two dates and return in hours and minutes

Hello I want to return in my PostgreSQL the difference between two dates:
START: 2016-06-01 00:00:00
END: 2016-06-06 08:35:33
Expected return value: 128:35:33, formatted like format [h]:mm:ss;# in Excel. Hours must be added up if there is more than 24 hours of difference.
Here's my SQL:
SELECT EXTRACT(EPOCH FROM dt_termino::timestamp - dt_inicio::timestamp)/3600 FROM crm.task_interacao WHERE id_task_tarefa = 1
UPDATE!!!
hello now i'm facing another problema I have a table like this:
my table in database like this
start;end
2013-06-01 09:29:33;2016-06-07 14:08:19
2016-06-07 14:22:09;2016-06-07 14:22:43
2016-06-07 14:22:51; null
i need to sum values ....i'm trying as you said (1st awnser).. I cant use function because i'm using inside a php code
SELECT SUM(COALESCE(end::timestamp, now()::timestamp) - start::timestamp) FROM crm.task_interacao WHERE id_task_tarefa = 1
but is returning
1102 days 26:07:54.864879
why 26 hours??? I was supose be te at maximum 24...
no problem now to return (Days HH:MM:SS) and not miliseconds
You can simply subtract timestamps to get interval:
select '2016-06-06 08:35:33'::timestamp- '2016-06-01 00:00:00' result
result
-----------------
5 days 08:35:33
(1 row)
There is no standard function to convert the result to the format you need but you can write one:
create or replace function interval_without_days(interval)
returns interval language sql as $$
select $1- date_part('day', $1)* '1d'::interval+ date_part('day', $1)* '24h'::interval;
$$;
select interval_without_days('2016-06-06 08:35:33'::timestamp- '2016-06-01 00:00:00');
interval_without_days
-----------------------
128:35:33
(1 row)
Question #2. Use the functions date_trunc(text, interval) and justify_hours(interval):
select date_trunc('sec', justify_hours('1102 days 26:07:54.864879'));
date_trunc
--------------------
1103 days 02:07:54
(1 row)