Oracle sql - get months id between two dates - sql

I have date range eg. '2021-01-05' and '2021-02-10'. Two months January and February.
Need resaults:
Months
------
1
2

You want to iterate through the months. This is done with a recursive query in SQL:
with months (month_start_date) as
(
select trunc(:start_date, 'month') from mytable
union all
select month_start_date + interval '1' month
from months
where month_start_date < trunc(:end_date, 'month')
)
select
extract(year from month_start_date) as year,
extract(month from month_start_date) as month
from months
order by month_start_date;

You can use EXTRACT function that Oracle has to achieve this. In your case it should look something like:
SELECT EXTRACT (month FROM date_column) as "Months"
For more information about this function you can check out documentation here.

Related

Oracle SQL - Define the year element of a date dependent on the current month

I am trying to create a view in SQL Developer based on this statement:
SELECT * FROM ORDERS WHERE START_DATE > '01-JUL-2020'
The year element of the date needs to set to the year of the current date if the current month is between July and December otherwise it needs to be the previous year.
The statement below returns the required year but I don't know how to incorporate it (or a better alternative) into the statement above:
select
case
when month(sysdate) > 6 then
year(sysdate)
else
year(sysdate)-1
end year
from dual
Thanks
Oracle doesn't have a built-in month function so I'm assuming that is a user-defined function that you've created. Assuming that's the case, it sounds like you want
where start_date > (case when month(sysdate) > 6
then trunc(sysdate,'yyyy') + interval '6' month
else trunc(sysdate,'yyyy') - interval '6' month
end)
Just subtract six months and compare the dates:
SELECT *
FROM ORDERS
WHERE trunc(add_months(sysdate, -6), 'YYYY') = trunc(start_date, 'YYYY')
This compares the year of the date six months ago to the year on the record -- which seems to be the logic you want.

How to assign mm/dd/yyyy records to associated Fiscal month found in another table

Note: this question is for both SQL and ORACLE and we do not have permissions for creation of temp table or stored procedures.
The database has two tables.
One table has a field of End Dates of Months along with a text field which identifies the "Fiscal Month" label.
Second table has dates by day (mm/dd/yyyy) with numeric data associated.
We need to retrieve the second table data (summing the numerics) grouping by the associated "Fiscal Month" found in table One.
Within one query or using CTE or a better solution, how to perform some kind of lookup on Table One to retrieve the Fiscal Month that the mm/dd/yyy date in Table two should be grouped on.
Table 1 (Fiscal Month End Dates)
2015-05-29 - Fiscal Month is 'May2015'
2015-06-30 - Fiscal Month is 'Jun2015'
2015-07-31 - Fiscal Month is 'Jul2015'
Table 2 (mm/dd/yyyy) which needs to be summed and grouped by Fiscal Month
2015-05-29 should be grouped on 'May2015'
2015-06-30 should be grouped on 'Jun2015'
So the approach I have used is to create a range of dates for a particular fiscal month.
Since you have the last dates of each fiscal month, you can get the previous one as the end of the previous fiscal month. Of course this is with a starting hard-limit because the first month in the fiscal month table will not have the previous month date (I used 1st of Jan of the year).
Then when you join it with your daily data, you can use these two dates to determine which fiscal month the data belongs to.
To get the previous fiscal month end date, we can use the LAG analytic function using the month to order the rows.
The rest of the query is pretty straightforward.
WITH
fiscal_end_dates
AS
(SELECT TO_DATE ('2015-05-29', 'YYYY-MM-DD') AS last_date FROM DUAL
UNION ALL
SELECT TO_DATE ('2015-06-30', 'YYYY-MM-DD') AS last_date FROM DUAL
UNION ALL
SELECT TO_DATE ('2015-07-31', 'YYYY-MM-DD') AS last_date FROM DUAL),
daily_data
AS
(SELECT TO_DATE ('2015-05-29', 'YYYY-MM-DD') AS data_date,
10 AS some_value
FROM DUAL
UNION ALL
SELECT TO_DATE ('2015-05-30', 'YYYY-MM-DD') AS data_date,
14 AS some_value
FROM DUAL
UNION ALL
SELECT TO_DATE ('2015-06-20', 'YYYY-MM-DD') AS data_date,
34 AS some_value
FROM DUAL
UNION ALL
SELECT TO_DATE ('2015-07-04', 'YYYY-MM-DD') AS data_date,
34 AS some_value
FROM DUAL),
fiscal_date_range
AS
(SELECT last_date,
NVL (
LAG (last_date, 1) OVER (ORDER BY EXTRACT (MONTH FROM last_date)),
TO_DATE (EXTRACT (YEAR FROM last_date) || '-01-01', 'YYYY-MM-DD')
)
AS prev_month_fiscal_end_date,
INITCAP (TO_CHAR (last_date, 'MON')) || EXTRACT (YEAR FROM last_date)
AS fiscal_month
FROM fiscal_end_dates)
SELECT dd.*,
fdr.fiscal_month
FROM daily_data dd,
fiscal_date_range fdr
WHERE dd.data_date > fdr.prev_month_fiscal_end_date
AND dd.data_date <= fdr.last_date;
This is the result (I took the liberty of adding a few more rows in your daily data table just to show the query working)
DATA_DATE SOME_VALUE FISCAL_MONTH
5/29/2015 10 May2015
5/30/2015 14 Jun2015
6/20/2015 34 Jun2015
7/4/2015 34 Jul2015
All you need to do now is to use the result set and perform your grouping and aggregation.

SELECT FROM TABLE by YEAR dynamically

I have a query (in Oracle SQL Developer) which is currently hard-coded to select all records from 2019, 2018, and 2017. Now that it's 2020, I'd like to change this to select going back three years dynamically, so that this query can work years from now without having to change the code.
I know that I can find all records from this specific date last year through the end of the year with -
SELECT * FROM TABLE
WHERE BOOKDATE >= add_months( sysdate, -12*1 );
So that would give me from 11-MAR-2019 through the end of 2019. But how do I select all records for the current year, last year, and two years ago (each year separately) - and not from this date specifically? BOOKDATE has the format DD-MON-YY.
You could extract the year and perform the calculation on it:
SELECT *
FROM mytable
WHERE EXTRACT(YEAR FROM bookdate) - EXTRACT(YEAR FROM SYSDATE) <= 3
You could try like this:
SELECT *
FROM TABLE
WHERE EXTRACT(YEAR from BOOKDATE) >= EXTRACT(YEAR from sysdate)-3

Know the week number of a month in bigquery

I want to know the week number of a month for a date in bigquery standard sql.In PostgreSQL if I write:
select To_char(current_date, 'YYYY-MM-W')<br>
It works for the date '25-04-2018' as 2018-04-4.
Here 2018 is the year, 04 is the month and 4 is the fourth week of the month in which the date falls.
I want something similar in bigquery standard sql.
If I write:
select format_date("%Y-%m",current_date())
It gives only 2018-04
I also want to know the week number of month.
Thank you in advance.
Here is solution (defining a UDF that you can use in a query) along with an example.
CREATE TEMP FUNCTION DateWithWeekOfMonth(date DATE) AS (
CONCAT(
FORMAT_DATE('%Y-%m-', date),
CAST(DIV(EXTRACT(DAY FROM date), 7) + 1 AS STRING)
)
);
SELECT date, DateWithWeekOfMonth(date)
FROM (
SELECT DATE '2018-04-01' AS date UNION ALL
SELECT DATE '2018-04-07' UNION ALL
SELECT DATE '2018-04-08' UNION ALL
SELECT DATE '2018-04-30'
);

How to format a Vertica date column into just the month?

I am trying to format a Vertica date column into only the month.
I would need the final value in some sort of date datatype so in the report I can order the results by date/time, not order by text. So that February sorts after January etc.
select TO_DATE(TO_CHAR(purchase_date), 'Month')
from transactions
order by 1;
I am also tried:
select TO_DATE(TO_CHAR(MONTH(purchase_date)), 'Month')
from transactions
order by 1;
The above statements produce an error "Invalid value for Month"
Any ideas?
How about this?
select to_char(purchase_date, 'Month')
from transactions
order by purchase_date;
You can order by columns that are not in the select list.
EDIT:
If you want to combine months from multiple years, the above will not work quite right. This will:
select to_char(purchase_date, 'Month')
from transactions
order by extract(month from purchase_date);
Select TO_CHAR((NOW() - INTERVALYM '1 MONTH'), 'MON');
Output:
JUN
This will help you get only the name of the previous month.
We can directly use date_part to get a month from the timestamp.
SELECT DATE_PART('MONTH', purchase_date) purchase_date
TO_DATE gives the complete date, if you only provide MM in the parameter then Vertica set default year and day.
Let suppose the month number is 8.
SELECT TO_DATE(purchase_date, 'MM')
Output: (0001-08-01)