I am trying to compare two dates and return TRUE if the first date is less than '1 year 1 day' from the second date.
Using 361 days instead of '1 year 1 day' returns FALSE, but this makes sense based on why justify_interval('360 days'::interval) results '1 year'.
But when I run
SELECT '2019-05-03'::timestamp - '2018-05-07'::timestamp < '1 year 1 day'::INTERVAL;
I get FALSE, and when I run
SELECT '2019-05-03'::timestamp - '1 year 1 day'::INTERVAL < '2018-05-07'::timestamp;
I get TRUE.
Why do these return different things?
I can't find it in the docs, but this is due to the way intervals represented and compared.
Note that:
select timestamp '2019-05-03' - timestamp '2018-05-07' < interval '366 day';
gives you the expected result of TRUE.
To compare two intervals, Postgres first converts the intervals to integers. This is done in a pretty naive way, where years are concerned:
/*
* interval_relop - is interval1 relop interval2
*
* Interval comparison is based on converting interval values to a linear
* representation expressed in the units of the time field (microseconds,
* in the case of integer timestamps) with days assumed to be always 24 hours
* and months assumed to be always 30 days. To avoid overflow, we need a
* wider-than-int64 datatype for the linear representation, so use INT128.
*/
So, your query is asking:
select 361 * 24 * 3600 * 1000000 < (1 * 12 * 30 * 24 * 3600 * 1000000) + (1 * 24 * 3600 * 1000000);
Or,
select 31,190,400,000,000 < 31,190,400,000,000;
which is obviously false. ^^
A have a table where each row is 300 seconds (or 5 minutes) apart. I need to aggregate the data on every hour and half hour, aggregating everything before and including the hour or half hour.
I've tried this code:
SELECT
to_timestamp(floor(a / 1800 )) *
1800)
AT TIME ZONE 'UTC' as interval_alias, SUM(b) as b_sum
FROM TABLE_NAME GROUP BY interval_alias
...and it aggregates the data on every hour and half hour, but it sum the values post the hour and half hour.
The table looks something like this:
a | b
-------------------------
1533045600 | 3
1533045900 | 5
1533046200 | 6
1533046500 | 3
1533046800 | 5
1533047100 | 2
1533047400 | 3
1533047700 | 8
1533048000 | 5
1533048300 | 5
1533048600 | 6
The actual result with the above code is:
a | b
-------------------------
1533045600 | 24
1533047400 | 27
The desired output is:
a | b
-------------------------
1533045600 | 3
1533047400 | 24
I used a simpler calculation for the interval_alias and with a GROUP BY you can only select aggregations or the columns that are part of the GROUP BY. (The SELECT * you posted in the question didn't look correct...)
SELECT
FLOOR(a/1800)*1800 AS interval_alias,
SUM(b) AS sum_b
FROM TABLE_NAME
GROUP BY interval_alias
See example code on SQL Fiddle
update:
This is close to your desired output but will include a third result as your test data spans over more than a half hour.
SELECT
FLOOR(a/1800)*1800 + SIGN(a%1800)*1800 AS interval_alias,
SUM(b) AS sum_b
FROM TABLE_NAME
GROUP BY interval_alias
ORDER BY interval_alias
I need a cron job. It should run be every day on Monday till Thursday, starting at 16:30, executing every 5 minutes till 03:30 AM next day. On Friday it will start at 16:30 executing every 5 minutes till Monday 03:30 AM. Thank you very much!
Based on your comment you need two records like this:
This cover:
Need to run every weekday from Monday till Thursday, starting at
23:05, exporting every 5 minutes till 11:00 AM next day
5,10,15,20,25,30,35,40,45,50,55 23 * * 1-4 command
*/5 0-11 * * 2-5 command
This cover:
On Friday start to run at 23:05 until Monday 11:00 AM
5,10,15,20,25,30,35,40,45,50,55 23 * * 5 command
*/5 * * * 6,7 command
*/5 0-11 * * 1 command
And when we optimize the cron records we will get something like:
*/5 0-11 * * 1-5 command
5,10,15,20,25,30,35,40,45,50,55 23 * * 1-5 command
*/5 * * * 6,7 command
EDIT1:
As per question change you need:
Monday till Thursday, starting at 16:30, executing every 5 minutes
till 03:30 AM next day
30,35,40,45,50,55 16 * * 1,2,3,4 command
*/5 17,18,19,20,21,22,23 * * 1,2,3,4,5 command
*/5 0,1,2 * * 2,3,4,5 command
0,5,10,15,20,25 3 * * 2,3,4,5 command
On Friday it will start at 16:30 executing every 5 minutes till Monday
03:30 AM
30,35,40,45,50,55 16 * * 5 command
*/5 * * * 6,7 command
*/5 0,1,2 * * 1 command
0,5,10,15,20,25 3 * * 1 command
And to "optimize" the cron records
30,35,40,45,50,55 16 * * 1-5 command
*/5 0,1,2 * * 1,2,3,4,5 command
0,5,10,15,20,25 3 * * 1,2,3,4,5 command
*/5 17,18,19,20,21,22,23 * * 1,2,3,4,5 command
*/5 * * * 6,7 command
I want to be able to subtract the current time from the mod_date_time field.
This is what I have so far:
SELECT * FROM PROD_TRKG_TRAN.MOD_DATE_TIME - CURRENT_TIME WHERE USER_ID = '12345' * 24 * 60 "INTERVAL IN MINUTES"
Any help?
If you are using Oracle, you can use the following query:
SELECT (MOD_DATE_TIME - SYSDATE) * 24 * 60
FROM PROD_TRKG_TRAN
WHERE USER_ID = '12345';
How to make query in postgresql which will find all records which are started more than 6 hours ago?
In my table I have a column which stores utc time of last time used in milliseconds (long integer).
SELECT *
FROM exams
WHERE started < HERE_I_NEED_UTC_IN_MILLISECONDS - 6 * 60 * 1000 * 1000;
select *
from exams
where started < extract(epoch from (current_timestamp - interval '6' hour))