I have the following Oracle SQL code that works, but I would like to try and find a way to clean it up so it's not so repetitive. It is looking at orders for a part ordered each FY in an Oracle Database.
SELECT
-- Attribute
R.ASN,
-- Code for FY17
COUNT(CASE
WHEN R.DATE_BB IS NOT NULL
AND R.DATE_BB BETWEEN TO_DATE(EXTRACT(YEAR FROM SYSDATE) - 8 || '-10-01', 'YYYY-MM-DD')
AND TO_DATE(EXTRACT(YEAR FROM SYSDATE) - 7 || '-09-30', 'YYYY-MM-DD')
THEN R.ASN
END) +
COUNT(CASE
WHEN R.DATE_BB IS NULL
AND R.DATE_ALLOC BETWEEN TO_DATE(EXTRACT(YEAR FROM SYSDATE) - 8 || '-10-01', 'YYYY-MM-DD')
AND TO_DATE(EXTRACT(YEAR FROM SYSDATE) - 7 || '-09-30', 'YYYY-MM-DD')
THEN R.ASN
END) AS FY17,
-- Code for FY18
COUNT(CASE
WHEN R.DATE_BB IS NOT NULL
AND R.DATE_BB BETWEEN TO_DATE(EXTRACT(YEAR FROM SYSDATE) - 7 || '-10-01', 'YYYY-MM-DD')
AND TO_DATE(EXTRACT(YEAR FROM SYSDATE) - 6 || '-09-30', 'YYYY-MM-DD')
THEN R.ASN
END) +
COUNT(CASE
WHEN R.DATE_BB IS NULL
AND R.DATE_ALLOC BETWEEN TO_DATE(EXTRACT(YEAR FROM SYSDATE) - 7 || '-10-01', 'YYYY-MM-DD')
AND TO_DATE(EXTRACT(YEAR FROM SYSDATE) - 6 || '-09-30', 'YYYY-MM-DD')
THEN R.ASN
END) AS FY18,
-- Code for FY19
COUNT(CASE
WHEN R.DATE_BB IS NOT NULL
AND R.DATE_BB BETWEEN TO_DATE(EXTRACT(YEAR FROM SYSDATE) - 6 || '-10-01', 'YYYY-MM-DD')
AND TO_DATE(EXTRACT(YEAR FROM SYSDATE) - 5 || '-09-30', 'YYYY-MM-DD')
THEN R.ASN
END) +
COUNT(CASE
WHEN R.DATE_BB IS NULL
AND R.DATE_ALLOC BETWEEN TO_DATE(EXTRACT(YEAR FROM SYSDATE) - 6 || '-10-01', 'YYYY-MM-DD')
AND TO_DATE(EXTRACT(YEAR FROM SYSDATE) - 5 || '-09-30', 'YYYY-MM-DD')
THEN R.ASN
END) AS FY19,
-- Code for FY20
COUNT(CASE
WHEN R.DATE_BB IS NOT NULL
AND R.DATE_BB BETWEEN TO_DATE(EXTRACT(YEAR FROM SYSDATE) - 5 || '-10-01', 'YYYY-MM-DD')
AND TO_DATE(EXTRACT(YEAR FROM SYSDATE) - 4 || '-09-30', 'YYYY-MM-DD')
THEN R.ASN
END) +
COUNT(CASE
WHEN R.DATE_BB IS NULL
AND R.DATE_ALLOC BETWEEN TO_DATE(EXTRACT(YEAR FROM SYSDATE) - 5 || '-10-01', 'YYYY-MM-DD')
AND TO_DATE(EXTRACT(YEAR FROM SYSDATE) - 4 || '-09-30', 'YYYY-MM-DD')
THEN R.ASN
END) AS FY20,
-- Code for FY21
COUNT(CASE
WHEN R.DATE_BB IS NOT NULL
AND R.DATE_BB BETWEEN TO_DATE(EXTRACT(YEAR FROM SYSDATE) - 4 || '-10-01', 'YYYY-MM-DD')
AND TO_DATE(EXTRACT(YEAR FROM SYSDATE) - 3 || '-09-30', 'YYYY-MM-DD')
THEN R.ASN
END) +
COUNT(CASE
WHEN R.DATE_BB IS NULL
AND R.DATE_ALLOC BETWEEN TO_DATE(EXTRACT(YEAR FROM SYSDATE) - 4 || '-10-01', 'YYYY-MM-DD')
AND TO_DATE(EXTRACT(YEAR FROM SYSDATE) - 3 || '-09-30', 'YYYY-MM-DD')
THEN R.ASN
END) AS FY21,
-- Code for FY22
COUNT(CASE
WHEN R.DATE_BB IS NOT NULL
AND R.DATE_BB BETWEEN TO_DATE(EXTRACT(YEAR FROM SYSDATE) - 3 || '-10-01', 'YYYY-MM-DD')
AND TO_DATE(EXTRACT(YEAR FROM SYSDATE) - 2 || '-09-30', 'YYYY-MM-DD')
THEN R.ASN
END) +
COUNT(CASE
WHEN R.DATE_BB IS NULL
AND R.DATE_ALLOC BETWEEN TO_DATE(EXTRACT(YEAR FROM SYSDATE) - 3 || '-10-01', 'YYYY-MM-DD')
AND TO_DATE(EXTRACT(YEAR FROM SYSDATE) - 2 || '-09-30', 'YYYY-MM-DD')
THEN R.ASN
END) AS FY22,
-- Code for FY23
COUNT(CASE
WHEN R.DATE_BB IS NOT NULL
AND R.DATE_BB BETWEEN TO_DATE(EXTRACT(YEAR FROM SYSDATE) - 2 || '-10-01', 'YYYY-MM-DD')
AND TO_DATE(EXTRACT(YEAR FROM SYSDATE) - 1 || '-09-30', 'YYYY-MM-DD')
THEN R.ASN
END) +
COUNT(CASE
WHEN R.DATE_BB IS NULL
AND R.DATE_ALLOC BETWEEN TO_DATE(EXTRACT(YEAR FROM SYSDATE) - 2 || '-10-01', 'YYYY-MM-DD')
AND TO_DATE(EXTRACT(YEAR FROM SYSDATE) - 1 || '-09-30', 'YYYY-MM-DD')
THEN R.ASN
END) AS FY23,
-- Code for FY24
COUNT(CASE
WHEN R.DATE_BB IS NOT NULL
AND R.DATE_BB BETWEEN TO_DATE(EXTRACT(YEAR FROM SYSDATE) - 1 || '-10-01', 'YYYY-MM-DD')
AND TO_DATE(EXTRACT(YEAR FROM SYSDATE) || '-09-30', 'YYYY-MM-DD')
THEN R.ASN
END) +
COUNT(CASE
WHEN R.DATE_BB IS NULL
AND R.DATE_ALLOC BETWEEN TO_DATE(EXTRACT(YEAR FROM SYSDATE) - 1 || '-10-01', 'YYYY-MM-DD')
AND TO_DATE(EXTRACT(YEAR FROM SYSDATE) || '-09-30', 'YYYY-MM-DD')
THEN R.ASN
END) AS FY24
-- Table name in Oracle Database
FROM CLS_REQN_SHIP_ARCH R
WHERE R.ASN = 'S100-1A3PS1'
GROUP BY R.ASN;
I have tried loops, but loops are not supported in Oracle SQL within a single SQL query. Is there anything else I could look at to clean this up?