[UPDATED] Question:
The query that Leigh provided worked, but for some reason, when I replaced the names of the rows and columns to change the query from Cost Per Click to Cost per Registration and Cost per License, I would get different values than expected.
Note: The results I list below are only for the Cost per Registrations, not Cost per Licenses. Both come from the same table, so if one is fixed, most likely the second one will follow suit. I also updated the AdReport table to include the Licenses column etc.
What I expected
Date CPR
1 $31.35
2 $61.42
3 $77.85
4 $78.48
5 $55.11
What I got
Date CPR
1 971.9412
2 1781.2939
3 2421.733
4 2355.4679
5 1598.164
Queries:
<cfquery name="costPerRegistration" datasource="#dsn#">
SELECT ab.AdMonth AS Date,
CASE WHEN SUM(ar.Conversions) > 0 THEN SUM(ab.AdBudget) / SUM(ar.Conversions)
ELSE 0
END AS CPR
FROM AdBudget AS ab INNER JOIN AdReport AS ar
ON DATEPART(MONTH, ar.ReportDate) = ab.AdMonth
AND DATEPART(YEAR, ar.ReportDate) = ab.AdYear
AND ar.AdSourceID = ab.AdSourceID
WHERE ab.AdYear = '2016'
AND ar.AdSourceID != 4
GROUP BY ab.AdMonth
ORDER BY ab.AdMonth
</cfquery>
<cfquery name="costPerLic" datasource="#dsn#">
SELECT ab.AdMonth AS Date,
CASE WHEN SUM(al.Licenses) > 0 THEN CAST(SUM(ab.AdBudget)/SUM(al.Licenses) AS smallmoney)
ELSE 0
END AS CPL
FROM AdBudget AS ab INNER JOIN AdReport AS al
ON DATEPART(MONTH,al.ReportDate) = ab.AdMonth
AND DATEPART(YEAR,al.ReportDate) = ab.AdYear
AND al.AdSourceID = ab.AdSourceID
WHERE ab.AdYear = 2016
AND ab.AdSourceID != 4
GROUP BY ab.AdMonth
ORDER BY ab.AdMonth
</cfquery>
Code:
<cfloop index = "i" from = "1" to = "#AdBudget.RecordCount#">
<cfset Clicks.Click[i] = AdBudget.Budgeting/Clicks.Click[i]>
<cfset Registrations.Conver[i] = AdBudget.Budgeting/Registrations.Conver[i]>
<cfset Licenses.License[i] = AdBudget.Budgeting/Licenses.License[i]>
</cfloop>
<!--- Bar graph, from Query of Queries --->
<cfchart>
<cfchartseries type="curve"
seriescolor="##5283DA"
serieslabel="Cost per Clicks"
<cfchartdata item="1" value="#Click#">
</cfchart>
</cfchart>
Data:
Sample Data added, disregard the sourceID and other IDs in the table.
AdBudgetID AdBudget AdMonth AdSourceID AdYear
1 7663 1 1 2016
2 20301 2 1 2016
3 5555 1 2 2016
4 16442 2 2 2016
5 1706 1 3 2016
6 4841 2 3 2016
7 11384 3 1 2016
8 23726 3 2 2016
9 9653 3 3 2016
13 17557.98 5 1 2016
14 25685.72 5 2 2016'
AdClickID AdClicks AdMonth AdSourceID AdYear
1 2229 1 1 2016
2 1803 1 2 2016
3 371 1 3 2016
4 4940 2 1 2016
5 5855 2 2 2016
6 673 2 3 2016
7 2374 3 1 2016
8 12913 3 2 2016
9 1400 3 3 2016
13 2374 4 1 2016
14 10272 4 2 2016
AdReportID ReportDate AdSourceID Clicks Conversions Demos Clients Licenses Onboardings AvgScore
2430 2016-03-27 1 1 1 0 0 0 0 NULL
2431 2016-03-27 2 5 0 0 0 0 0 NULL
2432 2016-03-27 3 1 0 0 0 0 0 NULL
2433 2016-03-27 5 24 0 0 0 0 0 NULL
2434 2016-03-27 6 0 0 0 0 0 0 NULL
2435 2016-03-27 6 0 0 0 0 0 NULL NULL
2436 2016-03-27 4 0 1 0 0 0 1 NULL
2437 2016-03-26 1 2 0 0 0 0 0 NULL
Sorry about the table config, not sure how to make it neat. Also, we have a lot more conversions(registrations) and licenses that are not shown in the sample data, it just happened that the first ~10 rows had low numbers.
how to set the chart up to chart them correctly
I would actually start with that question, rather than the queries. Start with a small hard coded chart, that is easy to adjust, in order to figure out exactly how the tags should be constructed to produce the desired chart. The final groupings will determine how you should aggregate the query data.
Say you want to chart the "Cost per click" and "Cost per Registration", for January to May of 2016, as separate series. Creating a hard coded example like this:
<cfchart>
<cfchartseries type="curve" serieslabel="Cost per Clicks">
<cfchartdata item="1" value="15">
<cfchartdata item="2" value="50">
<cfchartdata item="3" value="47">
<cfchartdata item="4" value="32">
<cfchartdata item="5" value="65">
</cfchartseries>
<cfchartseries type="curve" serieslabel="Cost per Registration">
<cfchartdata item="1" value="45.52">
<cfchartdata item="2" value="17.68">
<cfchartdata item="3" value="28.50">
<cfchartdata item="4" value="78.62">
<cfchartdata item="5" value="42.50">
</cfchartseries>
</cfchart>
Produces this chart:
Looking at the cfchartdata tags, indicates two queries are needed: one containing the "Cost per Click" by month, and another the "Cost per Registration" by month.
To calculate the cost per click, join AdBudget
and AdClick
on the month, year and source id columns. Group the results by month, and divide the total budget by the total clicks:
<cfquery name="costPerClick" ....>
SELECT ab.AdMonth
, CASE WHEN SUM(ac.AdClicks) > 0 THEN SUM(ab.AdBudget) / SUM(ac.AdClicks)
ELSE 0
END AS CostPerClick
FROM AdBudget ab LEFT JOIN AdClick ac
ON ac.AdMonth = ab.AdMonth
AND ac.AdYear = ab.AdYear
AND ac.AdSourceID = ab.AdSourceID
WHERE ab.AdYear = 2016
AND ab.AdSourceID <> 4
GROUP BY ab.AdMonth
ORDER BY ab.AdMonth
</cfquery>
Then simply loop through the query to generate the cfchartseries:
<cfchart>
<cfchartseries type="curve" serieslabel="Cost per Clicks">
<cfoutput query="costPerClick">
<cfchartdata item="#costPerClick.AdMonth#"
value="#DecimalFormat(costPerClick.Amount)#">
</cfoutput>
</cfchartseries>
</cfchart>
Using the hints above, you should be able to follow the same process to generate the other two queries and series.
Update:
Turns out I misunderstood the structure of AdReport. Since it contains multiple records for each month/year/sourceID combination, you will need a calculate the total conversions by month first. Then JOIN that result back to AdBudget. So the "Cost per Registration" query would need to be something like this:
SELECT ab.AdMonth
, CASE WHEN SUM(ar.Conversions) > 0 THEN SUM(ab.AdBudget) / SUM(ar.Conversions)
ELSE 0
END AS CPR
FROM AdBudget ab LEFT JOIN
(
/* Calculate total conversions per month */
SELECT AdSourceID
, DATEPART(MONTH, ReportDate) AS AdMonth
, DATEPART(YEAR, ReportDate) AS AdYear
, SUM(Conversions) AS Conversions
FROM AdReport
--- first of desired year (2016) to first of next year (exclusive)
WHERE ReportDate >= '2016-01-01'
AND ReportDate < '2017-01-01'
AND AdSourceID <> 4
GROUP BY AdSourceID
, DATEPART(MONTH, ReportDate)
, DATEPART(YEAR, ReportDate)
)
ar ON ar.AdMonth = ab.AdMonth
AND ar.AdYear = ab.AdYear
AND ar.AdSourceID = ab.AdSourceID
GROUP BY ab.AdMonth
ORDER BY ab.AdMonth