This question already has answers here:
Presto: Last day of the month prior
(2 answers)
Closed 4 months ago.
I understand Athena uses Presto, however the function last_day_of_month(x) in the documentation doesn't seem to work in AWS Athena.
Is there a function I can use to get the last day of the previous month based on the current date (30 september 2021), last day of previous year (31 december 2021) and last day of the half year (30 June 2022) etc?
I used the below script to do this, however it would be good to know if there's a function I can use or simpler way to run the dates.
SELECT date_trunc('month', current_date) - interval '1' day
SELECT date_trunc('year',(date_trunc('month', current_date) - interval '1' day)) - interval '1' day
SELECT date_add('month',6, date_trunc('year',(date_trunc('month', current_date) - interval '1' day)) - interval '1' day)
First, you need to upgrade your Workgroup to use the Athena engine version 3, which already supports last_day_of_month(x) function.
Athena is based on Presto/Trino, and each version of the Athena engine is based on a different version of the open-source project. You can control the version from the Workgroups menu and even let Athena upgrade the engine automatically for you.
Second, if you want a get the last day of the previous month, the easiest way is to create the first day of the following month and substruct one day from it.
SELECT date '2012-08-01' - interval '1' day
Therefore, if you want the last day of the previous month, and as suggested in the comment, using date_trunc:
SELECT date_trunc('month', current_date ) - interval '1' day
--- half year back
SELECT date_trunc('month', current_date - interval '6' month) - interval '1' day
--- one year back
SELECT date_trunc('month', current_date - interval '1' year) - interval '1' day
Related
I am trying to set up a scheduled query to run on the 1st of each month, and capture one month of data. However it should not be the previous month, but 2 months previous - due to delays in data being loaded in to the source table. The source table is partitioned by day on session_timestamp so refining this as much as possible will be of benefit to reducing query cost.
So far I have this:
WHERE
EXTRACT(YEAR
FROM
session_timestamp) = EXTRACT(YEAR
FROM
DATE_SUB(CURRENT_DATE, INTERVAL 2 MONTH))
AND EXTRACT(MONTH
FROM
session_timestamp) = EXTRACT(MONTH
FROM
DATE_SUB(CURRENT_DATE, INTERVAL 2 MONTH))
This seems a highly inelegant solution but was intended to address cases where a year boundary would be crossed. However I can see from the "This script will process * when run." area that this is going to query everything in 2020 and not just in May 2020.
As you have pointed out, your query doesn't engage partition filter down to the 2 months of data which you want to query.
You don't have to do the year trick because DATE_TRUNC(..., MONTH) has year in it. Please try filter below:
-- Last day of the month
DATE(session_timestamp) <= DATE_SUB(DATE_TRUNC(DATE_SUB(CURRENT_DATE(), INTERVAL 1 MONTH), MONTH), INTERVAL 1 DAY)
AND
-- First day of the month
DATE(session_timestamp) >= DATE_TRUNC(DATE_SUB(CURRENT_DATE(), INTERVAL 2 MONTH), MONTH)
I used postgresql to solve the quesion, query to return the day of the week of the first day of the month two years from today. I was able to solve it with the query below, but I am not sure my query is correct, I just wanna make sure
select cast(date_trunc('month', current_date + interval '2 years') as date)
You are correctly computing the first day of the month two years later with:
date_trunc('month', current_date + interval '2 years')
If you want the corresponding day of the week, you can use extract();
extract(dow from date_trunc('month', current_date + interval '2 years'))
This gives you an integer value between 0 (Sunday) and 6 (Saturday)
I am looking for a function in SQL that can help me compute an aggregate for same period last month or same period last year. For example, Today is 14th November and my current revenue month to date is 1000$. I am looking for a function in SQL that can sum up revenue for for the previous month i.e sept but only for the same period of 14 days. Is there a function that can achieve this??
The AGO function in OBIEE (RPD) does this with ease, I am looking to do this using SQL. Any ideas?
That could be as simple as
SELECT sum(gains)
FROM business_transactions
WHERE billing_date
BETWEEN date_trunc('month', current_timestamp - INTERVAL '1 month')
AND current_timestamp - INTERVAL '1 month');
How can I select first day of last month and last day of next month in HSQL database?
I tried it postgres way like follows:
SELECT date_trunc('month', current_date - INTERVAL '1 month') :: DATE AS first_day_of_last_month;
Does not work in Java HSQL database thou. :(
Use the LAST_DAY(date) function.
LAST_DAY(CURRENT_DATE - 2 MONTH) + 1 DAY
LAST_DAY(CURRENT_DATE + 1 MONTH)
I've been fighting with an issue about querying the records where created_at is within the current, or past x weeks. Say, today is Wednesday, so that'd be from Monday at midnight, up to now, if x = 1. If x > 1, I'm looking for current week, up to today, or past week, but not using regular interval '1 week' as that'll get me Wednesday to Wednesday, and I'm only looking into "whole" weeks.
I've tried the interval-solution, and also things like WHERE created_at > (CURRENT_DATE - INTERVAL '5 week').
A solution that'll work for both day, month, year etc, would be preferred, as I'm actually building the query through some other backend logic.
I'm looking for a generic query for "Find everything that's been created 'x periods' back.
Edit:
Since last time, I've implemented this in my Ruby on Rails application. This has caused some problems when using HOUR. The built is working for everything but HOUR (MONTH, DAY, and YEAR)
SELECT "customer_uses".*
FROM "customer_uses"
WHERE (customer_uses.created_at > DATE_TRUNC('MONTH', TIMESTAMP '2017-09-17T16:45:01+02:00') - INTERVAL '1 MONTH')
Which works correctly on my test cases. (Checking count of this). The TIMESTAMP is generated by DateTime.now to ensure my test-cases working with a time-override for "time-travelling"-tests, therefore not using the built in function.
(I've stripped away some extra WHERE-calls which should be irrelevant).
Why the HOUR isn't working is a mystery for me, as I'm using it with a interpolated string for HOUR instead of MONTH as above like so:
SELECT "customer_uses".*
FROM "customer_uses"
WHERE (customer_uses.created_at > DATE_TRUNC('HOUR', TIMESTAMP '2017-09-17T16:45:21+02:00') - INTERVAL '1 HOUR')
Your current suggested query is almost right, except that it uses the current date instead of the start of the week:
SELECT * FROM your_table WHERE created_at > (CURRENT_DATE - INTERVAL '5 week')
Instead, we can check 5 week intervals backwards, but from the start of the current week:
SELECT *
FROM your_table
WHERE created_at > DATE_TRUNC('week', CURRENT_DATE) - INTERVAL '5 week';
I believe you should be able to use the above query as a template for other time periods, e.g. a certain number of months. Just replace the unit in DATE_TRUNC and in the interval of the WHERE clause.