Within Crystal Reports, I’m using the following query (against an Oracle database) to generate data for a single field in a report:
SELECT SUM(e1.ENT_LOCAL_AMOUNT+e1.ENT_DISCRETIONARY_AMOUNT) AS "Entitlement"
FROM CLAIM_PERIODS cp1
JOIN ENTITLEMENTS e1
ON cp1.CPE_REFNO=e1.ENT_CPE_REFNO
WHERE e1.ENT_REFNO=(SELECT MAX(to_number(e2.ENT_REFNO))
FROM ENTITLEMENTS e2
WHERE e1.ENT_CPE_REFNO=e2.ENT_CPE_REFNO
AND (e2.ENT_START_DATE <= {?HB_As_At_Date}
AND e2.ENT_END_DATE > {?HB_As_At_Date})
AND e2.ENT_CREATED_DATE<={?HB_As_At_Date})
AND cp1.CPE_CPA_CPY_CODE='HB'
This works fine and returns a single integer value, based on the {?HB_As_At_Date} supplied (The {?} syntax is Crystal’s way of embedding parameter values into SQL). The content of the above query isn’t my issue though – what I want to do is run it repeatedly for several different dates, and have that output be what gets fed through to Crystal for use in the report.
So say I want this query run for every Monday in September, I’d currently run the Crystal report once with a parameter of 07/09/2015, then again for 14/09/2015, etc.
I’d instead like to use my SELECT statement in conjunction with a query that tabulates this as needed – running the above once each per date required. With the output being something like:
Date Entitlement
07/09/2015 450,000.00
14/09/2015 460,123.00
21/09/2015 465,456.00
28/09/2015 468,789.00
Could someone point me in the right direction in terms of which keywords I should be reading up on here? I’d imagine it’s quite straight-forward to generate a set of dates and run my SQL as a subquery using them, but I’m not sure where to start.
Advertisement
Answer
The only way I can think of without using a stored procedure is by repeating (i.e. copy/paste) your query for each date parameter and then combining them as sub-queries using UNION. Something like this:
SELECT SUM(e1.ENT_LOCAL_AMOUNT+e1.ENT_DISCRETIONARY_AMOUNT) AS "Entitlement"
FROM CLAIM_PERIODS cp1
JOIN ENTITLEMENTS e1
ON cp1.CPE_REFNO=e1.ENT_CPE_REFNO
WHERE e1.ENT_REFNO=(SELECT MAX(to_number(e2.ENT_REFNO))
FROM ENTITLEMENTS e2
WHERE e1.ENT_CPE_REFNO=e2.ENT_CPE_REFNO
AND (e2.ENT_START_DATE <= {?HB_As_At_Date_1}
AND e2.ENT_END_DATE > {?HB_As_At_Date_1})
AND e2.ENT_CREATED_DATE<={?HB_As_At_Date_1})
AND cp1.CPE_CPA_CPY_CODE='HB'
UNION
SELECT SUM(e1.ENT_LOCAL_AMOUNT+e1.ENT_DISCRETIONARY_AMOUNT) AS "Entitlement"
FROM CLAIM_PERIODS cp1
JOIN ENTITLEMENTS e1
ON cp1.CPE_REFNO=e1.ENT_CPE_REFNO
WHERE e1.ENT_REFNO=(SELECT MAX(to_number(e2.ENT_REFNO))
FROM ENTITLEMENTS e2
WHERE e1.ENT_CPE_REFNO=e2.ENT_CPE_REFNO
AND (e2.ENT_START_DATE <= {?HB_As_At_Date_2}
AND e2.ENT_END_DATE > {?HB_As_At_Date_2})
AND e2.ENT_CREATED_DATE<={?HB_As_At_Date_2})
AND cp1.CPE_CPA_CPY_CODE='HB'
As for your comment about writing a script for that, I don’t know how you are running your report. But if you have an app/website running it, then you can generate the SQL in the app/website’s language and assign it to the report object before you run it. Or even better, you can generate the SQL, run it, and assign the results to the report object. I do this all the time as I prefer my code to run the queries rather than the report itself, because I follow the layered design pattern in my app. The report will be located in the presentation layer which cannot communicate with the database directly, instead it calls the business/data layer with generates/runs the query and returns the results to the business/presentation layer.