PostgreSQL - Add days to current_data with condition - postgresql

I'm trying to add a day to current_date in between only when from hour is bigger then to hour
can any one help?
see code:
AND EXISTS(SELECT *
FROM jsonb_array_elements((${hours})::jsonb) hours(e)
WHERE hours.e->'active' = 'true'
AND now() BETWEEN
current_date +
(LEFT(hours.e->>'from', 2))::INTEGER * INTERVAL '1 HOUR' +
(RIGHT(hours.e->>'from', 2))::INTEGER * INTERVAL '1 MINUTE' AND
current_date +
// add day if from is bigger then to
(LEFT(hours.e->>'to', 2))::INTEGER * INTERVAL '1 HOUR' +
(RIGHT(hours.e->>'to', 2))::INTEGER * INTERVAL '1 MINUTE' )
a

Related

PostgreSQL: Date Calendar Days Interval Scenario

I would like to print this table (displaying only 4 rows for brevity):
Dates
Period
01-MAR-2022
61
02-MAR-2022
61
03-MAR-2022
61
30-APR-2022
61
So far I have:
SELECT CAST(TRUNC(date_trunc('month',CURRENT_DATE) + interval '-2 month') AS DATE) + (n || 'day')::INTERVAL AS Dates
, date_trunc('month',CURRENT_DATE) + interval '-2 month' + INTERVAL '2 month' - date_trunc('month',CURRENT_DATE) + interval '-2 month' AS Period
FROM generate_series(0,61) n
Please help with a better way of generating the period and also replacing the hard-coded 61 in generate_series(0,61).
Thanks!
What are you actually trying to accomplish, it is not clear nor specified. BTW your query is invalid. It appears you looking to list each data from first date of 2 months prior to the last date of 1 month prior and the total number of days in that range. The following would give the first date, and using date subtraction gives the number of days.
with full_range( first_dt, num_days) as
( select date_trunc ('month', (current_date - interval '2 months'))::date
, date_trunc ('month', (current_date - interval '1 day'))::date -
date_trunc ('month', (current_date - interval '2 months'))::date
)
select *
from full_range;
With that in hand you can use the num_days with generate series with the expression
select generate_series(0, num_days-1) from full_range
Finally combine the above arriving at: (see demo)
with full_range( first_dt, num_days) as
( select date_trunc ('month', (current_date - interval '2 months'))::date
, date_trunc ('month', (current_date - interval '1 day'))::date -
date_trunc ('month', (current_date - interval '2 months'))::date
)
select (first_dt + n*interval '1 day')::date, num_days
from full_range
cross join (select generate_series(0, num_days-1) from full_range) gn(n);

How to get the 1st 6months i.e.(1-26weeks) and last 6months (26-52 weeks) from last year & also get last 5weeks from current date using postgresql

How to get the 1st 6months i.e.(1-26weeks) and last 6months (26-52 weeks) from last year & also how to get last 5weeks from current date using postgresql.
Like the below table structure
Id Title Description current_week_number current_year
-----------------------------------------------------
123 abc descr 48 2021
456 def descr1 45 2020
Based on the week number and year I'm trying to fetch the data.
can anyone help on this?
Thanks
Query the table on the last 6 months until now :
SELECT *
FROM your_table
WHERE (current_year || '0101') :: date + interval '7 days' * current_week >= Now() - interval '6 months'
AND (current_year || '0101') :: date + interval '7 days' * current_week <= Now()
Query the table between the last 12 months and the last 6 months from now :
SELECT *
FROM your_table
WHERE (current_year || '0101') :: date + interval '7 days' * current_week <= Now() - interval '6 months'
AND (current_year || '0101') :: date + interval '7 days' * current_week >= Now() - interval '12 months'
Query the table for the first 6 months of the current year :
SELECT *
FROM your_table
WHERE (current_year || '0101') :: date + interval '7 days' * current_week >= (extract(year from Now()) || '0101') :: date
AND (current_year || '0101') :: date + interval '7 days' * current_week <= (extract(year from Now()) || '0101') :: date + interval '6 months'
Query the table for the last 6 months of the current year :
SELECT *
FROM your_table
WHERE (current_year || '0101') :: date + interval '7 days' * current_week >= (extract(year from Now()) || '0101') :: date + interval '6 months'
AND (current_year || '0101') :: date + interval '7 days' * current_week <= (extract(year from Now()) || '0101') :: date + interval '12 months'
--records from 1st half of this year, based on week number
select Id, Title, Description, current_week_number, current_year
from your_table
where current_year=extract('year' from now())::int
and current_week_number<=26;
--records from 2nd half of this year, based on week number
select Id, Title, Description, current_week_number, current_year
from your_table
where current_year=extract('year' from now())::int
and current_week_number>26;
As to the original form of the question, getting the actual weeks:
using generate_series(date,date,interval) and extract('field' from date).
with first_26_weeks_of_last_year as
( select extract('week' from weeks) weeks
from generate_series(
make_date( extract('year' from 'today'::timestamp-'1 year'::interval)::int,
1,
1
),
make_date( extract('year' from 'today'::timestamp-'1 year'::interval)::int,
1,
1
)+'25 weeks'::interval,
'1 week'::interval) weeks),
last_6_months_of_last_year as
( select extract('week' from weeks) weeks
from generate_series(
make_date( extract('year' from 'today'::timestamp-'1 year'::interval)::int,
12,
31
),
make_date( extract('year' from 'today'::timestamp-'1 year'::interval)::int,
12,
31
)-'6 months'::interval,
'1 week'::interval) weeks),
five_weeks_from_this_week as
( select extract('week' from weeks) weeks
from generate_series(
'today'::date,
'today'::date+'4 weeks'::interval,
'1 week'::interval) weeks)
select 'first_26_weeks_of_last_year',a.weeks
from first_26_weeks_of_last_year a
union all
select 'last_6_months_of_last_year',a.weeks
from last_6_months_of_last_year a
union all
select 'five_weeks_from_this_week',a.weeks
from five_weeks_from_this_week a;

How to use COALESCE with INTERVAL in PostgreSQL?

This is a syntax error, but didn't see what the correct syntax would be.
The goal is to handle the case where days is null.
SELECT * FROM tbl WHERE created_at > current_date - INTERVAL 'COALESCE(%days%, 999) DAY'
You can multiply COALESCE(%days%, 999) to an interval of 1 day:
SELECT * FROM tbl
WHERE created_at > current_date - COALESCE(%days%, 999) * INTERVAL '1 DAY'
Use make_interval()
SELECT *
FROM tbl
WHERE created_at > current_date - make_interval(days:=COALESCE(%days%, 999));

Postgresql compare two select result on the same table

I compare results from two selects and get 1 or 0 as a final result.
Below query syntax is good but this query causes timeout.
SELECT (CASE WHEN (
select count(*) from order where ordered_date > (NOW() - INTERVAL '120 minutes')
and order_ordered = current_date) >
(select count(*)/3
from order
where ordered_date > (NOW() - INTERVAL '2 days' - INTERVAL '120 minutes')
and ordered_date < (NOW() - INTERVAL '2 days'))
THEN 1 ELSE 0 end);
Therefore, i try to optimize the query to use an alias for each select as below :
select (case when a > b then 1 else 0 end) from (select count(*) from order where ordered_date > (NOW() - INTERVAL '120 minutes')
and order_ordered = current_date) as a,
from (select count(*)/3
from order
where ordered_date > (NOW() - INTERVAL '2 days' - INTERVAL '120 minutes')
and ordered_date < (NOW() - INTERVAL '2 days'))as b;
I have syntax error near "from", in my memory this kind of syntax works on mysql.
Could you please advise me if there a possiblity to use two times of "from" by using alias on Postgresql or if you know another possility i am a taker.
Sample:
First query gives : select count(*) from order where ordered_date > (NOW() - INTERVAL '120 minutes') and order_ordered = current_date -> 60
Seconde query gives : select count(*)/3 from order where ordered_date > (NOW() - INTERVAL '2 days' - INTERVAL '120 minutes') and ordered_date < (NOW() - INTERVAL '2 days') -> 20
Final condition : case when (60 > 20 then 1 else 0 end)
Result expected : 1
Thanks
I suggest using SELECT in WITH (here documentation).
WITH orders_current_date AS (
SELECT count(*)
FROM order
WHERE ordered_date > (NOW() - INTERVAL '120 minutes')
AND order_ordered = current_date)
), orders_interval AS (
SELECT count(*)/3
FROM order
WHERE ordered_date > (NOW() - INTERVAL '2 days' - INTERVAL '120 minutes')
AND ordered_date < (NOW() - INTERVAL '2 days')
)
SELECT
CASE
WHEN SELECT * FROM orders_current_date > SELECT * FROM orders_interval
THEN '1'
ELSE
0
END;

How to get average between two dates in PostgreSql

I'd like to get the average date between two dates in Postgres:
In SqlServer is done with this simple query:
SELECT DateAdd(ms, DateDiff(ms, date_begin, date_end)/2, date_begin)
For example:
SELECT DateAdd(ms, DateDiff(ms, getdate(), dateadd(d, 1, getdate()))/2, getdate())
Now I'd like to make the same query in postgres.
I try with something like
SELECT current_timestamp + ((SELECT ((DATE_PART('day', (current_timestamp + INTERVAL '1 day')::timestamp - current_timestamp::timestamp) * 24 +
DATE_PART('hour', (current_timestamp + INTERVAL '1 day')::timestamp - current_timestamp::timestamp)) * 60 +
DATE_PART('minute', (current_timestamp + INTERVAL '1 day')::timestamp - current_timestamp::timestamp)) * 60 +
DATE_PART('second', (current_timestamp + INTERVAL '1 day')::timestamp - current_timestamp::timestamp)||'second')::interval
but it does not work.
Is there a simpler way to make this simple operation in Postgres?
How about:
select date_begin + (date_end - date_begin)/2