问题
I have been provided the below SQL query and am looking to modify it. Currently this is only pulling the last 4 months worth of data. I am trying to modify it to run from December 1 through the current month. If anyone is able to guide me through this, that would be greatly appreciated.
Select NVL(x.COUNT, 0) + z.COUNT As "Number of RMAs",
Case z.MONTH When 1 Then 'Jan.' When 2 Then 'Feb.' When 3 Then 'Mar.'
When 4 Then 'Apr.' When 5 Then 'May' When 6 Then 'Jun.' When 7 Then 'Jul.'
When 8 Then 'Aug.' When 9 Then 'Sep.' When 10 Then 'Oct.'
When 11 Then 'Nov.' When 12 Then 'Dec.' Else 'error' End As "Month",
z.YEAR,
'28.00' As GOAL,
Round(Avg(NVL(x.COUNT, 0) + z.COUNT) Over (Order By z.YEAR, z.MONTH Rows
Between 2 Preceding And Current Row), 2) As ROLL3MOAVG
From (Select Count(RMA.ID) As count,
Extract(Month From RMA.RMA_DATE) As month,
Extract(Year From RMA.RMA_DATE) As year
From RMA,
(Select Unique RMA_DETAIL.RMA_ID
From RMA_DETAIL
Where RMA_DETAIL.RETURN_CODE_ID > 0 And RMA_DETAIL.RETURN_CODE_ID <
100) RMA_DETAIL
Where RMA.ID = RMA_DETAIL.RMA_ID And RMA.RMA_DATE >= SysDate - 400
Group By Extract(Month From RMA.RMA_DATE),
Extract(Year From RMA.RMA_DATE)) x,
(Select 0 As count,
Extract(Month From Add_Months(SysDate - 120, (Level - 1))) As month,
Extract(Year From Add_Months(SysDate - 120, (Level - 1))) As year
From dual
Connect By Level <= 13) z
Where z.MONTH = x.MONTH(+) And z.YEAR = x.YEAR(+)
Order By z.YEAR,
z.MONTH
回答1:
Don't have access to any sample data, so I would try the following: The correlated subquery aliased as "z" calculates your date boundaries:
SELECT 0 AS count,
EXTRACT(MONTH FROM Add_Months(SysDate - 120, (LEVEL - 1))) AS month,
EXTRACT(YEAR FROM Add_Months(SysDate - 120, (LEVEL - 1))) AS year
FROM dual
CONNECT BY LEVEL <= 13
COUNT MONTH YEAR
---------- ---------- ----------
0 2 2020
0 3 2020
0 4 2020
0 5 2020
0 6 2020
0 7 2020
0 8 2020
0 9 2020
0 10 2020
0 11 2020
0 12 2020
0 1 2021
0 2 2021
It starts with the month 120 days ago (SysDate - 120) and adds 12 month rows. Run this query in sqldeveloper to check what it does. You'll see it starts in feb 2020 and ends in feb 2021. If you replace that query with a query that starts on dec 1st up till now it should work:
SELECT 0 AS count,
EXTRACT(MONTH FROM ADD_MONTHS(TO_DATE('01-DEC-2019','DD-MON-YYYY'), (LEVEL - 1))) As month,
EXTRACT(YEAR FROM ADD_MONTHS(TO_DATE('01-DEC-2019','DD-MON-YYYY'), (LEVEL - 1))) As year
FROM dual
CONNECT BY LEVEL <= ROUND(MONTHS_BETWEEN(SYSDATE,TO_DATE('01-DEC-2019','DD-MON-YYYY'))) + 1
COUNT MONTH YEAR
---------- ---------- ----------
0 12 2019
0 1 2020
0 2 2020
0 3 2020
0 4 2020
0 5 2020
0 6 2020
explanation:
start with
ADD_MONTHS(TO_DATE('01-DEC-2019','DD-MON-YYYY'), (LEVEL - 1)). Your first row will be LEVEL 1 so this will return December.CONNECT BY LEVEL <= ROUND(MONTHS_BETWEEN(SYSDATE,TO_DATE('01-DEC-2019','DD-MON-YYYY'))) + 1: add a month up til current month so calculate the number of months between now and dec 1st and add 1.
For getting a query that works for every year (there must be cleaner ways to write this but I can't think of any now), use the following:
SELECT 0 AS count,
EXTRACT(MONTH FROM ADD_MONTHS(TO_DATE('01-DEC-'||TO_CHAR(ADD_MONTHS(SYSDATE,-11),'YYYY'),'DD-MON-YYYY'), (LEVEL - 1))) As month,
EXTRACT(YEAR FROM ADD_MONTHS(TO_DATE('01-DEC-'||TO_CHAR(ADD_MONTHS(SYSDATE,-11),'YYYY'),'DD-MON-YYYY'), (LEVEL - 1))) As year
FROM dual
CONNECT BY LEVEL <= ROUND(MONTHS_BETWEEN(SYSDATE,TO_DATE('01-DEC-'||TO_CHAR(ADD_MONTHS(SYSDATE,-11),'YYYY'),'DD-MON-YYYY'))) + 1
来源:https://stackoverflow.com/questions/62201907/sql-showing-rolling-4-months-looking-for-fiscal-year