Decrease Date( Month ) in postgres - sql

I want to minus three months from 2014-11-05 23:18:07.452957-07. It should give output like 2014-08-05 23:18:07.452957-07
I am trying this:
SELECT created_on, DATE (created_on - INTERVAL '5 months') FROM user_authentication_logs
WHERE user_id = 1014 ORDER BY created_on DESC LIMIT 1
But date format is changed. Please help.
Thanks in advance.

For first, just remove the Date casting by replacing the:
SELECT created_on, DATE (created_on - INTERVAL '5 months') FROM user_authentication_logs
WHERE user_id = 1014 ORDER BY created_on DESC LIMIT 1
by
SELECT created_on, created_on - INTERVAL '5 months' as created_on_minus_5_months FROM user_authentication_logs
WHERE user_id = 1014 ORDER BY created_on DESC LIMIT 1
Because Date type contains only date (no times)
And if your date format output is changed you can customize it using the t_char fucntion

Try This out
I think This is you want
SELECT created_on, cast((created_on - INTERVAL '5 months')as timestamp with time zone) FROM user_authentication_logs
WHERE user_id = 1014 ORDER BY created_on DESC LIMIT 1;

Related

Postgresql Distinct Statement

How can i get the minutes distinct value with timestamp ...
Like , if table contains 1 minute 100 records are there...so i want count of records present or not per minute ...
For example,
SELECT DISTINCT(timestamp) FROM customers WHERE DATE(timestamp) = CURRENT_DATE
Result should be ..like
timestamp record
30-12-2019 11:30 5
30-12-2019 11:31 8
One option would be ::date conversion for timestamp column including GROUP BY :
SELECT timestamp, count(*)
FROM tab
WHERE timestamp::date = current_date
GROUP BY timestamp
Demo for current day
timestamp::date might be replaced with date(timestamp) like in your case.
Update : If the table contains data with precision upto microseconds, then
SELECT to_char(timestamp,'YYYY-MM-DD HH24:MI'), count(*)
FROM tab
WHERE date(timestamp) = current_date
GROUP BY to_char(timestamp,'YYYY-MM-DD HH24:MI')
might be considered.
Try something like the following:
SELECT DATE_TRUNC('minute', timestamp) as timestamp, COUNT(*) as record
FROM customers
WHERE DATE(timestamp) = CURRENT_DATE
GROUP BY DATE_TRUNC('minute', timestamp)
ORDER BY DATE_TRUNC('minute', timestamp)

Select Data From Multiple Days Between Certain Times (Spanning 2 days)

I need to know how many entries appear in my DB for the past 7 days with a timestamp between 23:00 & 01:00...
The Issue I have is the timestamp goes across 2 days and unsure if this is even possible in the one query.
So far I have come up with the below:
select trunc(timestamp) as DTE, extract(hour from timestamp) as HR, count(COLUMN) as Total
from TABLE
where trunc(timestamp) >= '12-NOV-19' and
extract(hour from timestamp) in ('23','00','01')
group by trunc(timestamp), extract(hour from timestamp)
order by 1,2 desc;
The result I am hoping for is something like this:
DTE | Total
20-NOV-19 5
19-NOV-19 4
18-NOV-19 4
17-NOV-19 6
Many thanks
Filter on the day first comparing it to TRUNC( SYSDATE ) - INTERVAL '7' DAY and then consider the hours by comparing the timestamp to itself truncated back to midnight with an offset of a number of hours.
select trunc(timestamp) as DTE,
extract(hour from timestamp) as HR,
count(COLUMN) as Total
from TABLE
WHERE timestamp >= TRUNC( SYSDATE ) - INTERVAL '7' DAY
AND ( timestamp <= TRUNC( timestamp ) + INTERVAL '01:00' HOUR TO MINUTE
OR timestamp >= TRUNC( timestamp ) + INTERVAL '23:00' HOUR TO MINUTE
)
group by trunc(timestamp), extract(hour from timestamp)
order by DTE, HR desc;
Subtract or add an hour to derive the date. I'm not sure what date you want to assign to each period, but the idea is:
select trunc(timestamp - interval '1' hour) as DTE,
count(*) as Total
from t
where trunc(timestamp - interval '1' hour) >= DATE '2019-11-12' and
extract(hour from timestamp) in (23, 0)
group by trunc(timestamp - interval '1' hour)
order by 1 desc;
Note: If you want times between 11:00 p.m. and 1:00 a.m., then you want the hour to be 23 or 0.

Select timestamp range in SQL

I am trying to select a specific time range on a specific days range in SQL postgres. PLease see the code below which gives an error on the '10:00:00'.
The type of data for each columns is :
numeric for "balance",
character varying(255) for "currency",
timestamp without time zone for "created_at" (ex: 2018-03-20 00:00:00).
I tried this link without success.
MySQL select based on daily timestamp range
SELECT SUM(bl.balance) AS balance, bl.currency, bl.created_at
FROM balance_logs bl
WHERE bl.balance_scope = 'system' AND
created_at >= CURRENT_DATE - 2 AND
created_at < CURRENT_DATE AND
created_at BETWEEN '10:00:00' AND '11:00:00'
GROUP BY bl.currency, bl.created_at
ORDER BY created_at DESC
The comparison needs to be as a time:
SELECT SUM(bl.balance) AS balance, bl.currency, bl.created_at
FROM balance_logs bl
WHERE bl.balance_scope = 'system' AND
created_at >= CURRENT_DATE - 2 AND
created_at < CURRENT_DATE AND
created_at::time BETWEEN '10:00:00'::time AND '11:00:00'::time
GROUP BY bl.currency, bl.created_at
ORDER BY created_at DESC;
However, I think it is better to write the WHERE condition as:
extract(hour from created_at) = 10

Select date and hour in query conditions

I am using PGADMIN 4 on postgres database. I would like to extract using the following query but adding hour as well. current date at 6am for example.
Thank you
SELECT object_key, audited_changes, created_at
FROM pg_audits
WHERE
source_action = 'funding' AND
created_at >= CURRENT_DATE -1 AND
created_at < CURRENT_DATE
ORDER BY
created_at DESC
You can write any number of hours in place of N
SELECT object_key, audited_changes, (created_at + INTERVAL 'N HOURS') as created_at
FROM pg_audits
WHERE
source_action = 'funding' AND
created_at >= CURRENT_DATE -1 AND
created_at < CURRENT_DATE
ORDER BY
created_at DESC

How to GROUP BY date with a timestamp field in Postgres?

Lets say that I have 3 rows of data:
id product_uuid version_uuid created_at
22 586d8e21b9529d14801b91bd 5a711a0094df04e23833d8ef 2018-02-10 19:51:15.075-05
23 586d8e21b9529d14801b91bd 5a711a0094df04e23833d8ef 2018-02-10 19:51:16.077-07
24 586d8e21b9529d14801b91bd 5a711a0094df04e23833d8ef 2018-02-11 19:51:15.077-05
And I want to group them by day via the created_at column.
SELECT created_at::date, COUNT(*)
FROM table_name
WHERE product_uuid = '586d8e21b9529d14801b91bd'
AND created_at > now() - interval '30 days'
GROUP BY created_at
ORDER BY created_at ASC
I would expect this to yield 2 rows:
created_at count
2018-02-10 2
2018-02-11 1
But I actually get 3 rows:
created_at count
2018-02-10 1
2018-02-10 1
2018-02-11 1
I realize that GROUP BY is still grouping by the fine-grain timestamp, but I'm not sure how to make Postgres use the truncated date instead.
You need to truncate in the GROUP BY as well:
SELECT created_at::date, COUNT(*)
FROM table_name
WHERE product_uuid = '586d8e21b9529d14801b91bd' AND
created_at > now() - interval '30 days'
GROUP BY created_at::date
ORDER BY created_at::date ASC;
Your version is aggregating by each date/time value but only showing the date component.
Also, I would recommend that you use current_date rather than now() so the first date is not truncated.
You query groups by individual time stamps (which include the time of day), and then converts them to dates after they are grouped. If you want a row per date, you should add the conversion to date in the group by clause too:
SELECT created_at::date, COUNT(*)
FROM table_name
WHERE product_uuid = '586d8e21b9529d14801b91bd'
AND created_at > now() - interval '30 days'
GROUP BY created_at::date -- Here!
ORDER BY created_at 1 ASC
You need to format the date as a string. So do this instead:
SELECT to_char(created_at,'YYYY-MM-DD'), COUNT(*) AS `Count`
FROM table_name
WHERE product_uuid = '586d8e21b9529d14801b91bd'
AND created_at > now() - interval '30 days'
GROUP BY to_char(created_at,'YYYY-MM-DD')
ORDER BY to_char(created_at,'YYYY-MM-DD') ASC;