Getting records relative to current date in timezone GMT+8 - sql

I wanted to create a report that generate yesterdays records relative to current date in Manila time. Result of the query is wrong until 8AM in Manila time.
I tried subtracting 1 day in current date and convert it in Asia/Manila timezone.
SELECT *
FROM table
WHERE date_field >= current_date at time zone 'Asia/Manila' - interval '1 day'
AND date_field < current_date at time zone 'Asia/Manila'
If today's current date time in manila is 2019-05-25 1AM
My expected result is records from '2019-05-24 00:00:00' - '2019-05-24 23:59:59'
But what I've got is records from '2019-05-23 00:00:00' - '2019-05-23 23:59:59'
Tried running it again at 8AM same date and the result is correct.

This is a little complicated. The current_date is defined at the UTC date. So, when you are calling it, the UTC date is "yesterday", and you are off by one day.
One way to fix this moves the current time into the time zone and then converts to a date:
WHERE date_field >= (current_timestamp at time zone 'Asia/Manila' - interval '1 day')::date AND
date_field < (current_timestamp at time zone 'Asia/Manila')::date

Related

Select data between dates and between times of day

I want to query rows for a given time range and also filter between given times of day.
Example I want to filter for times of day between '9.00 AM' and '10.00 PM' of every date within a given time range.
My table looks like this.
This is my sample code:
SELECT *
FROM public.energy
WHERE time >= date_trunc('month', NOW() - INTERVAL '1 MONTH') AT TIME ZONE 'Asia/Bangkok'
AND time < date_trunc('MINUTE', NOW()- INTERVAL '1 MONTH') AT TIME ZONE 'Asia/Bangkok'
AND name = 'SWU0001'
ORDER BY id DESC;
I already select data between dates that I want, but I want to filter for specific times.
SELECT *
FROM public.energy
WHERE name = 'SWU0001'
AND time >= date_trunc('month' , now() AT TIME ZONE 'Asia/Bangkok' - interval '1 month') AT TIME ZONE 'Asia/Bangkok' -- !
AND time < date_trunc('minute', now() AT TIME ZONE 'Asia/Bangkok' - interval '1 month') AT TIME ZONE 'Asia/Bangkok' -- !
AND (time AT TIME ZONE 'Asia/Bangkok')::time BETWEEN '09:00' AND '22:00' -- !!!
ORDER BY id DESC;
Don't call a timestamptz column "time". The name is misleading, and it's a basic type name.
Also, to work with local time of 'Asia/Bangkok' you need to get the local time for that time zone before applying date_trunc(), and cast the adjusted value back to timestamptz at the end. Basics:
Ignoring time zones altogether in Rails and PostgreSQL

Presto TIMESTAMP get data from 2 days ago without inputting year month date?

My goal is to have the query grab data from 2 days ago. I don't want to have to keep inputting the date like this:
WHERE usage_start_date
BETWEEN TIMESTAMP '2020-09-09 00:00:00.000' and TIMESTAMP '2020-09-09
23:59:59.999'
but instead something like:
usage_start_date = current_date - interval '2' day
the above works for my Athena Presto SQL query, but for some reason will not give all the data that ran in those 24 hours, instead giving about half the day. Is there a way to do a statement like this one to ensure it gives ALL data in that day?
WHERE current_date - interval '2' day AND
BETWEEN TIMESTAMP '00:00:00.000' and TIMESTAMP '23:59:59.999'
without inputting the year, month, day? It seems like TIMESTAMP needs the y/m/d but what about doing a LIKE so it picks up the hour, minute, second but no need to put the y/m/d?
To get a timestamp for the start of the day that was two days ago you can do
DATE_TRUNC('day', NOW() - INTERVAL '2' DAY)
e.g.
WHERE usage_start_date >= DATE_TRUNC('day', NOW() - INTERVAL '2' DAY)
AND usage_start_date < DATE_TRUNC('day', NOW() - INTERVAL '1' DAY)
You can use below query to achieve the task by fetching the hour and date from the usage_start_date
select * from table where hour(usage_start_date) between 0 and 23 and current_date - interval '2' day = date(usage_start_date)
I would suggest:
WHERE usage_start_date >= CURRENT_DATE - INTERVAL '2' DAY AND
usage_start_date < CURRENT_DATE - INTERVAL '1' DAY

Difference between CURRENT_TIMESTAMP and CURRENT_DATE

I want to get the data from the last 28 days and only include complete days. So what I mean is, when I look at the data today at 10:00 AM, it only includes data from yesterday (the completed day) and 28 days before yesterday.
I am creating a live dashboard with figures like this. So I don't want the numbers to change until the day is finished.
Also, I am willing to understand the difference between CURRENT_DATE and CURRENT_TIMESTAMP
For example, in my code, if I use CURRENT_TIMESTAMP, will I get the data from today 10:00 AM back to 28 days ago 10:00 AM? if not, how can I get data in a way numbers change live according to every time I run the code (the average time that data change in the database is 10 minutes).
My simplified code:
select count(id) from customers
where created_at > CURRENT_DATE - interval '28 days'
Maybe I am using wrong code, can you please give me advice on how to get the date in both formats:
include only complete days(does not include today, until the day is
finished)
include hours, from today morning until 28 days back same
time in the morning.
Assuming created_at is of type timestamptz.
include only complete days(does not include today, until the day is
finished)
Start with now() and use date_trunc():
SELECT count(*)
FROM customers
WHERE created_at < date_trunc('day', now())
AND created_at >= date_trunc('day', now() - interval '28 days');
Or work with CURRENT_DATE ...
WHERE created_at < CURRENT_DATE
AND created_at >= CURRENT_DATE - 28;
The result for both depends on the current timezone setting. The "date" functionally depends on your current time zone. The type timestamp with time zone (timestamptz) does not. But the expression date_trunc('day', now()) introduces the same dependency as the "day" is defined by your current time zone. So you need to define which "days" you mean precisely. Basics:
Ignoring time zones altogether in Rails and PostgreSQL
You can subtract integer values from a date to subtract days:
How do I determine the last day of the previous month using PostgreSQL?
now() is a shorter equivalent of CURRENT_TIMESTAMP. See:
Difference between now() and current_timestamp
count(*) is equivalent to count(id) while id is defined NOT NULL, but a bit faster.
I have different results from query for COUNT('e.id') or COUNT(e.id)
include hours, from today morning until 28 days back same time in the morning.
Simply:
WHERE created_at > now() - interval '28 days'
No dependency on the current time zone.

How to query for "Yesterday, in my timezone" when all my timestamps are UTC

I am trying to include, in my where clause, a way to automatically pull data for the previous day based on my current timezone. All of my data is stored with a UTC timestamp.
I can change my timestamp from UTC to my timezone ("America/Chicago") and I can automatically pull data for the last X days; for example, for the prior week, without having to manually enter a date. But I cannot figure out how to do both simultaneously in my where clause.
SELECT *
FROM `my-data-set`
WHERE
event_time >= CAST(DATE_SUB(CURRENT_DATE(), INTERVAL 7 DAY) AS TIMESTAMP)
AND event_time < CAST(DATE_SUB(CURRENT_DATE(), INTERVAL 0 DAY) AS TIMESTAMP)
I would like to be able to look at the previous week or day in my timezone, not the previous UTC day.
You can do specify the timezone:
where date(event_time, 'America/Chicago') = date_add(current_date, interval -1 day)
Note that the parentheses are not needed for current_date.
The key to the logic is converting the UTC timestamp to a date in your local time.

How to compare dates one with time zone and one without time zone

I have to compare the two dates to get the last 10 min records from database,I'm using postgresql,
I have write this query
select *
FROM x_table
WHERE x_time >= (NOW()::TIMESTAMP WITHOUT TIME ZONE - interval '10 minutes');
x_time is timestamp without time zone so that's why i'm converting the other to the same but it won't giving the result.
Query should written the last 1 min records but i think due to time zone issue it is not giving the result.
how can i resolve the issue?
If x_time is timestamp without time zone, you should specify proper time zone for NOW() function.
Try
select *FROM x_table WHERE x_time >= (NOW() at time zone '-04' - interval '10 minutes')