Select timestamp range in SQL - 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

Related

Equivalence of DATEADD in PostgreSQL?

I have this query that I used to be able to run in SQL server but cannot in PostgreSQL. Can you provide a query that will do the same as I cannot use DATEADD for Postgres.
select *
from VTable
where join_date>='1/1/2020' and join_date<'1/1/2021'
and join_date>= DATEADD(day,-30, removed_date)
and lremoved = 1
and countryid = '100010'
order by join_date asc
As documented in the manual you can add an integer to a date value which represents the number of days to add.
Also: ANSI date literals are preferred over locale specific date (or timestamp) values as they are unambiguous.
select *
from VTable
where join_date >= date '2020-01-01'
and join_date < date '2021-01-01'
and join_date >= removed_date - 30
and lremoved = 1
and countryid = '100010'
order by join_date asc
If join_date is a timestamp rather than a date, use an interval:
and join_date >= removed_date - interval '30 days'
The above is all standard ANSI SQL which Postgres happens to honor.

PostgreSQL - Select Query between today's start time and end time

I need to query database like - SELECT FROM table_name WHERE created_at = <--BETWEEN TODAY'S START AND END DATETIME-->
Sample data from created_at column is - 2020-09-28 17:02:14
Tried method is as follows but it didn't work,
SELECT FROM users WHERE created_at=CURRENT_TIMESTAMP;
SELECT FROM users WHERE created_at=CURRENT_DATE;
Can any one help me with this query
Is this what you want?
where created_at >= current_date
and created_at < current_date + interval '1 day'
This gives you all rows whose created_at belongs to the current day.

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;

Decrease Date( Month ) in postgres

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;