Grouping by Fiscal Year (Oracle) - oracle

Is there a way in Oracle that can pull the FY? I used the script below to pull just two FY. Mytable date range is from FY1998 to FY2009.
SELECT 'FY2008' as FY,
Site,
COUNT(*)
FROM mytable
WHERE date >='10-OCT-2007'
AND date <'10-OCT-2008'
GROUP BY site
SELECT 'FY2008' as FY,
Site,
COUNT(*)
FROM mytable
WHERE date >='10-OCT-2008'
AND date <'10-OCT-2009'
GROUP BY site
Pulling two FY is OK but it's too much repeatative when pulling more than 10 FY.

Add 83 days to your date and truncate it to whole year:
select 'FY'||TRUNC(date + 83, 'YYYY') as FY, Site, count(*)
from mytable
group by 'FY'||TRUNC(date + 83, 'YYYY'), site

Assuming Oracle 9i+, use a CASE expression:
SELECT CASE
WHEN TO_CHAR(t.date, ) = 10 AND EXTRACT(DAY FROM t.date) >= 10 THEN
'FY' || EXTRACT(YEAR FROM t.date) + 1
WHEN TO_CHAR(t.date, ) > 10 THEN
'FY' || EXTRACT(YEAR FROM t.date) + 1
ELSE
'FY' || EXTRACT(YEAR FROM t.date)
END AS FY,
t.site,
COUNT(*)
FROM YOUR_TABLE t
GROUP BY t.site, FY

And for completeness, in addition to #eumiro answer. In countries (such as Australia) which have a financial year running from 1 July to 30 June, you can replace the 83 with 184.

A few options:
You can use the to_char function here. Check this link for an explanation:
http://www.techonthenet.com/oracle/functions/to_char.php
You may also try using a case statement
select case when date >='10-OCT-2007' and date <'10-OCT-2008' then 'FY08'
when date >='10-OCT-2008' and date <'10-OCT-2009' then 'FY09'
else 'Other' end as fiscal_year, count(*)
from mytable
group by case when date >='10-OCT-2007' and date <'10-OCT-2008' then 'FY08'
when date >='10-OCT-2008' and date <'10-OCT-2009' then 'FY09'
else 'Other' end
Ultimately, if you have create table privileges you may want to consider making a date lookup table. Search for "date dimension" in data warehousing guides.
For example:
Your table would have
date, date_desc, fiscal_year, etc....
then you could just join and group by fiscal year, or whatever else you want.

Here is another way to easily determine the Fiscal Year of a date for those who's Fiscal Year runs from July to June:
SELECT 'FY'||TO_CHAR(ROUND(your_date_here,'YEAR'),'YY') AS FY

Related

how to get year and month into number oracle

i'm trying to get sysdate year and month into number or char.
I'd want something like this:
202107
or last month
202106
i tried this code:
select trunc(add_months(sysdate, -1), 'MM') from dual;
please help, thanks
Convert it to a string and then to a number:
SELECT TO_NUMBER(TO_CHAR(ADD_MONTHS(SYSDATE,-1), 'YYYYMM'))
FROM DUAL;
Or, you can use extract and wrap it in a sub-query so you do not need to repeat adding the months:
SELECT EXTRACT(YEAR FROM dt) * 100 + EXTRACT(MONTH FROM dt)
FROM (
SELECT ADD_MONTHS(SYSDATE, -1) AS dt
FROM DUAL
)
Like
SELECT EXTRACT(year from sysdate) * 100 + EXTRACT(month from sysdate)
If you want to scroll around, manipulate the date before you extract from it, rather than minusing after you extract (gets tricky to e.g. go back a month if the date is in jan)
--will work for jan 2021
SELECT EXTRACT(year from ADD_MONTHS(somedate, -1)) * 100 + EXTRACT(month from ADD_MONTHS(somedate, -1))
--won't work for jan 2021
SELECT EXTRACT(year from somedate) * 100 + (EXTRACT(month from somedate) - 1)
TRUNC is a device that "rounds" a date to a particular interval, such as "trimming the time off a datetime" or "making any day of the week back to the date that was the start of the week" - very useful for all sorts of stuff like "total sales by month - SUM(sale) GROUP BY TRUNC(saledate, 'mm')" but it keeps all the components of the date (the day, the hour, the minute etc) so it isn't what you want.

How to get data from first day of the month until yesterday

does anyone know the query to get data from first day of the month until yesterday? I Try using query below but the problem is when today is the first day of the month, so the value become between 20170201 and 20170131
select * from a where to_char(DATE,'yyyymmdd') BETWEEN to_char(sysdate,'yyyymm')||'01' and to_char(sysdate-1,'yyyymmdd')
Ex: if today is 01-02-2017 i want to select the data from 01-01-2017 until 31-01-2017, but if today is 13-02-2017 i want to select the data from 01-02-2017 until 12-02-2017, thank's before
This question has been updated with your new logic. The query below will retain records under the following conditions:
someDate falls between the first day and yesterday of the current month, or
someDate, when today is the first of the month, falls anywhere in the previous month
SELECT *
FROM yourTable
WHERE someDate BETWEEN CASE WHEN EXTRACT(DAY FROM SYSDATE) = 1
THEN TRUNC(SYSDATE-1, 'MONTH')
ELSE TRUNC(SYSDATE, 'MONTH') END AND
CASE WHEN EXTRACT(DAY FROM SYSDATE) = 1
THEN TRUNC(SYSDATE, 'MONTH') - 1
ELSE TRUNC(SYSDATE - 1) END
This query assumes that you have a DATE column called someDate.

Birt Report and Date Parameter between current year and previous year

I am using the following query that was suggested to me by a fellow from stackoverflow. The following query is using the dates in order to bring the current year (>2016,<2017) and the previous year (>2015, <2016). I want to use this in a Birt report - and particularly prompt the user to select the date (by default the current date will be selected) and automatically the query will subtract a year in order to calculate the current year's results and the previous year's results. Here's the code given to me
SELECT grade,
COUNT( DISTINCT CASE WHEN DATE '2015-01-01' >= date_column
AND date_column < DATE '2016-01-01'
THEN customer_id END
) AS number_of_unique_customers_in_2015,
COUNT( DISTINCT CASE WHEN DATE '2016-01-01' >= date_column
AND date_column < DATE '2017-01-01'
THEN customer_id END
) AS number_of_unique_customers_in_2016
FROM Customers
WHERE Date_Column >= DATE '2015-01-01'
AND Date_Column < DATE '2017-01-01'
GROUP BY grade;
Can anyone suggest how to do this in the birt report?
Have a look at my answer here to see how to add parameters to a SQL query in Birt. You should add your Report Parameter to input the date from the user first.
To substract a year from the input parameter you should use DATEADD with a negative value for one year inside your SQL query where you add the parameter.
your query should look like this for the Input-Parameter date 2016-01-01:
SELECT grade,
COUNT( DISTINCT CASE WHEN DATEADD(year, -1, ?) >= date_column
AND date_column < ?
THEN customer_id END
) AS number_of_unique_customers_in_last_year,
COUNT( DISTINCT CASE WHEN ? >= date_column
AND date_column < DATEADD(year, 1, ?)
THEN customer_id END
) AS number_of_unique_customers_in_current_year
FROM Customers
WHERE Date_Column >= DATEADD(year, -1, ?)
AND Date_Column < DATEADD(year, 1, ?)
GROUP BY grade;

Oracle SQL display a different column depending on the date

I have a table that has 33 columns
Employee Month Day1 Day2 ...... etc. etc.
The day column represents the day of the month.
Is it possible to just display the Employee column and the Day of the month depending on today's date?
i.e.
12th May
Employee Day12
no idea where to start if it's possible. any help would be great
You get a record (here: month) with the WHERE clause. You get a certain column (here: day) with DECODE or CASE.
select
employee,
decode( extract(day from sysdate), 1, day1, 2, day2, 3, day3, ... ) as day
from mytable t
where t.month = extract(month from sysdate)
group by employee
order by employee;

Alternate for decode function

I have a table 'Holiday' which lists a set of holiday details.If i specify a date,I should obtain a result date after 5 days of specified date.If there is holiday in between it should exclude them and display the non holiday date.I have table named holiday which includes holiday date,holiday type|(weekly off,local holiday).Now i have used nested decode for continuous holiday checking.Tell me how this can be changed in case function.
DECODE
(date,
holidaydate, DECODE
(date + 1,
holidaydate + 1, DECODE
(date + 2,
holidaydate + 2, DECODE
(date + 3,holidaydate+3,date+4,date+3),date+2),date+1),date);
This can be achieved with a simple subquery which counts the number of holiday dates between a specified date and date+5. The following will return a date that is five non-holiday days in the future:
testdate+(select 5+count(1)
from holiday
where holidaydate between testdate
and testdate + 5)
Simply change both "5"s so another number to change the evaluation period.
SQLFiddle here
Edit - based on comment below, my code doesn't evaluate any days after the fifth day. This would probably be much easier with a function, but the following cte-based code will work also:
with cte as ( (select alldate,holidaydate
from (select to_date('20130101','yyyymmdd')+level alldate
from dual
connect by level < 10000 -- adjust for period to evaluate
) alldates
left join holiday on alldate=holidaydate) )
select
testdate,test_plus_five
from (
select
alldate test_plus_five,testdate,
sum(case when holidaydate is null
then 1
else 0 end) over (partition by testdate order by alldate) lastday
from
cte,
testdates
where
alldate >= testdate
group by
alldate,holidaydate,testdate)
where
lastday = 6
This script builds a calendar table so it can evaluate each day (holiday or non-holiday); then we get a running count of non-holiday days, and use the sixth one.
SQLFiddle here
AFAIK, You can use CASE alternative to DECODE in Oracle
CASE [ expression ]
WHEN condition_1 THEN result_1
WHEN condition_2 THEN result_2
...
WHEN condition_n THEN result_n
ELSE result
END
Finally i found the optimal solution.Thanks for ur response guys. SELECT dt FROM
(SELECT dt FROM (SELECT TO_DATE('15-AUG-2013','dd-mon-yyyy')+LEVEL dt FROM DUAL
CONNECT BY LEVEL < 30)
WHERE
(SELECT COUNT (*) FROM mst_holiday WHERE holidaydate = dt) = 0 )
where rownum=1

Resources