CF query remove empty string results for total sum - coldfusion

I am trying to fix my query so that my total sum column will equal the correct number. I tried changing this line <cfset columnSum = ArraySum(allLocCode['locationCount'])> to <cfset columnSum = ArraySum(trim(allLocCode['locationCount']))> But it through an error. I want the empty string like in the picture below to not be counted for the total just like it does not show in the table. Is there another way to pull off this trim for my total column?
<cfset result = {} />
<cftry>
<cfquery datasource="#application.dsn#" name="GetLocationInfo">
SELECT *
FROM cl_checklists
</cfquery>
<cfcatch type="any">
<cfset result.error = CFCATCH.message >
<cfset result.detail = CFCATCH.detail >
</cfcatch>
</cftry>
<table border="1" id="Checklist_Stats">
<thead>
<th><strong>Location</strong></th>
<th><strong>Percent of Total Checklists</strong></th>
<th><strong>Location Total</strong></th>
</thead>
<tbody>
<cfquery name="allLocCode" dbtype="query">
SELECT DISTINCT trans_location, COUNT(*) AS locationCount FROM GetLocationInfo GROUP BY trans_location ORDER BY trans_location
</cfquery>
<cfloop query="allLocCode">
<cfset thisLocationName = trim(allLocCode.trans_location) />
<cfquery name="allLocCodeForLocationQry" dbtype="query">
SELECT trans_location,count(*) AS locCntr FROM GetLocationInfo WHERE trans_location='#thisLocationName#' GROUP BY trans_location ORDER BY trans_location
</cfquery>
<cfoutput query="allLocCodeForLocationQry">
<tr>
<td><strong>#thisLocationName#</strong></td>
<td>#NumberFormat((allLocCodeForLocationQry.locCntr/allLocCode.locationCount) * 100, '9.99')#%</td>
<td>#allLocCodeForLocationQry.locCntr#</td>
</tr>
</cfoutput>
</cfloop>
<cfset columnSum = ArraySum(allLocCode['locationCount'])>
<tr>
<td><strong>Total</strong></td>
<td></td>
<td><cfoutput>#columnSum#</cfoutput></td>
<cfdump var="#allLocCode#">
<cfdump var="#allLocCodeForLocationQry#">
<cfdump var="#thisLocationName#">
</tr>
</tbody>
<!--- Total of All Sum of each column --->
</table>
The correct answer should reflect 334 not 340

As requested, here's an answer with the relevant code isolated:
<cfquery name="allLocCode" dbtype="query">
SELECT DISTINCT trans_location, COUNT(*) AS locationCount
FROM GetLocationInfo
WHERE trans_location is not null
GROUP BY trans_location
ORDER BY trans_location
</cfquery>
If you need more help with the percentage stuff I'd recommend starting a new post. I see from your history you already have several threads kind of related to this feature, and as it gets more complicated it'll help to separate everything.

Related

notify a user if there are no matching records found - coldfusion

How do you create something to notify a user if there are no matching records found with the queries you run?
I have a queries.cfm that I run like this:
<cfset result = {} />
<cftry>
<cfset date1 = CREATEODBCDATETIME(form.StartDate & '00:00:00')>
<cfset date2 = CREATEODBCDATETIME(form.EndDate & '23:59:59')>
<cfquery datasource="#application.dsn#" name="GetEmployeeInfo">
SELECT trans_location, date, associate
FROM cl_checklists
WHERE date >= <cfqueryparam value="#date1#" cfsqltype="cf_sql_timestamp" />
AND date <= <cfqueryparam value="#date2#" cfsqltype="cf_sql_timestamp" />
AND trans_location IN ( <cfqueryparam value="#FORM.location#" cfsqltype="cf_sql_varchar" list="true" /> )
AND associate IN ( <cfqueryparam value="#FORM.EmployeeName#" cfsqltype="cf_sql_varchar" list="true" /> )
</cfquery>
<cfquery datasource="#application.dsn#" name="GetLocationInfo">
SELECT trans_location, date, associate
FROM cl_checklists
WHERE date >= <cfqueryparam value="#date1#" cfsqltype="cf_sql_timestamp" />
AND date <= <cfqueryparam value="#date2#" cfsqltype="cf_sql_timestamp" />
AND trans_location IN ( <cfqueryparam value="#FORM.location#" cfsqltype="cf_sql_varchar" list="true" /> )
</cfquery>
<cffunction name="getop_id" access="public" returntype="string">
<cfargument name="associate" >
<cfquery name="spitOutop_id" datasource="#application.userinfo_dsn#">
SELECT assoc_name
FROM dbo.tco_associates
WHERE assoc_id= #arguments.associate#
</cfquery>
<cfreturn spitOutop_id.assoc_name >
</cffunction>
<cfquery name="allAssociatesQry" dbtype="query">
SELECT DISTINCT associate, COUNT(*) AS associateCount FROM GetEmployeeInfo GROUP BY associate ORDER BY associate
</cfquery>
<table border="1" id="Checklist_Stats">
<thead>
<th><strong>Associate Name</strong></th>
<th><strong>Location</strong></th>
<th><strong>Checklists Generated by Associate</strong></th>
<th><strong>Checklists Generated by Selected Location(s)</strong></th>
<th><strong>Associate Percentage of Location Total</strong></th>
</thead>
<tbody>
<!--- aggregate variables --->
<cfset aggrAssociateChecklist = 0>
<cfset aggrLocationChecklist = 0>
<cfloop query="allAssociatesQry">
<!--- get Associate's name --->
<cfset thisAssociateCode = trim(allAssociatesQry.associate)>
<cfset thisAssociateName = getop_id(thisAssociateCode) />
<!--- 1.1 get all trans_location code and total counts for the current Associate --->
<cfquery name="allLocCodeForAssociateQry" dbtype="query">
SELECT trans_location,count(trans_location) AS locCntr FROM GetEmployeeInfo WHERE associate='#thisAssociateCode#' GROUP BY trans_location ORDER BY trans_location
</cfquery>
<!--- 1.2 get the aggregate of checklist count generated by the current Associate for each location --->
<cfquery name="qTotalChecklistCountForAssociate" dbtype="query">
SELECT SUM(locCntr) AS totalAssocChecklist FROM allLocCodeForAssociateQry
</cfquery>
<!--- 2.1 get the total location checklist for each location available for the current Associate --->
<cfquery name="allLocChecklistForAssociateQry" dbtype="query">
SELECT trans_location,count(trans_location) AS totalLocCount FROM GetLocationInfo WHERE trans_location IN (#QuotedValueList(allLocCodeForAssociateQry.trans_location)#) GROUP BY trans_location ORDER BY trans_location
</cfquery>
<!--- 2.2 get the aggregate of location checklist generated by the current Associate --->
<cfquery name="qTotalLocChecklistForAssociate" dbtype="query">
SELECT SUM(totalLocCount) AS totalLocChecklist FROM allLocChecklistForAssociateQry
</cfquery>
<!--- display record for the current Associate --->
<cfoutput query="allLocCodeForAssociateQry">
<tr>
<!---<td><strong>#thisAssociateCode#</strong></td>--->
<td><strong>#thisAssociateName#</strong></td>
<td>#allLocCodeForAssociateQry.trans_location#</td>
<td>#allLocCodeForAssociateQry.locCntr#</td>
<td>#allLocChecklistForAssociateQry['totalLocCount'][CurrentRow]#</td>
<td>#NumberFormat((allLocCodeForAssociateQry.locCntr/allLocChecklistForAssociateQry['totalLocCount'][CurrentRow]) * 100, '9.99')#%</td>
</tr>
<cfset thisAssociateName = "" />
</cfoutput>
<!--- 3.1 get sub total for each Associate group --->
<cfset totalAssocChecklist = qTotalChecklistCountForAssociate.totalAssocChecklist>
<cfset totalLocChecklist = qTotalLocChecklistForAssociate.totalLocChecklist>
<!--- 3.2 add to the aggregate --->
<cfset aggrAssociateChecklist += totalAssocChecklist>
<cfset aggrLocationChecklist += totalLocChecklist>
<!--- display sub total for each Associate group --->
<cfoutput>
<tr>
<td>Associate Total</td>
<td></td>
<td>#totalAssocChecklist#</td>
<td>#totalLocChecklist#</td>
<td>#NumberFormat((totalAssocChecklist/totalLocChecklist) * 100, '9.99')#%</td>
</tr>
</cfoutput>
</cfloop>
<!--- display calculated aggregate at the end of the result --->
<!--- <cfoutput>
<tr>
<td><strong>Total</strong></td>
<td></td>
<td>#aggrAssociateChecklist#</td>
<td>#aggrLocationChecklist#</td>
<td>#NumberFormat((aggrAssociateChecklist/aggrLocationChecklist) * 100, '9.99')#%</td>
</tr>
</cfoutput>--->
</tbody>
</table>
<cfcatch type="any">
<cfset result.error = CFCATCH.message >
<cfset result.detail = CFCATCH.detail >
</cfcatch>
</cftry>
But I am trying to notify the user when no results come back based on there search.
I was trying to do a catch for the results if there 0 do something but have been unsuccessful. Would any Cold Fusion gurus like to assist me in how you alert your users when there query came back empty.
I tried:
<cfif #allAssociatesQry# is 0>
<cfif #allAssociatesQry# is null>
<cfif #allAssociatesQry# is "">
<cfif allAssociatesQry is 0>
<cfif allAssociatesQry is null>
<cfif allAssociatesQry is "">
Don't use try/catch. That's for code that doesn't run successfully. All you need is this:
<cfquery name="q">
sql
</cfquery>
<cfif q.recordcount is 0>
code for no records
<cfelse>
display records
</cfif>

CF Save As Dialog box and setting Save Type As

I am using CF 10 and I am trying to create a save as dialog box appear and set the save as type as xls (Excel Extension) so that my report can be easily saved in excel. I was thinking I could maybe do this with
<cfelseif FORM.Format IS "xls">
<cfcontent type="application/vnd.ms-excel">
<cfheader name="Content-Disposition" value="inline; filename=fileName.xls">
but that does not open up the correct dialog box. Does anyone know how this may be accomplished?
This is what should appear:
<cfelseif FORM.Format IS "xls">
<cfcontent type="application/vnd.ms-excel">
<cfheader name="Content-Disposition" value="inline; filename=fileName.xls">
<cfset result = {} />
<cftry>
<cfset date1 = CREATEODBCDATETIME(form.StartDate & '00:00:00')>
<cfset date2 = CREATEODBCDATETIME(form.EndDate & '23:59:59')>
<cfquery datasource="#application.dsn#" name="GetLocationInfo">
SELECT *
FROM cl_checklists
WHERE date >= <cfqueryparam value="#date1#" cfsqltype="cf_sql_timestamp" />
AND date <= <cfqueryparam value="#date2#" cfsqltype="cf_sql_timestamp" />
AND trans_location IN ( <cfqueryparam value="#FORM.location#" cfsqltype="cf_sql_varchar" list="true" /> )
</cfquery>
<cfquery name="allLocCode" dbtype="query">
SELECT DISTINCT trans_location, COUNT(*) AS locationCount FROM GetLocationInfo Where trans_location is not null GROUP BY trans_location ORDER BY trans_location
</cfquery>
<cfset columnSum = ArraySum(allLocCode['locationCount'])>
<cfset checkListPercentage = arrayNew(1)>
<table border="1" id="Checklist_Stats">
<thead>
<th><strong>Location</strong></th>
<th><strong>Percent of Total Checklists</strong></th>
<th><strong>Location Total</strong></th>
</thead>
<tbody>
<cfloop query="allLocCode">
<cfset thisLocationName = trim(allLocCode.trans_location) />
<cfquery name="allLocCodeForLocationQry" dbtype="query">
SELECT trans_location,count(*) AS locCntr FROM GetLocationInfo WHERE trans_location='#thisLocationName#' GROUP BY trans_location ORDER BY trans_location
</cfquery>
<cfoutput query="allLocCodeForLocationQry">
<cfset currentPercentage = (allLocCodeForLocationQry.locCntr / columnSum * 100)>
<cfset arrayAppend(checkListPercentage, currentPercentage)>
<cfset totalPercentage = arraySum(checkListPercentage)>
<tr>
<td><strong>#thisLocationName#</strong></td>
<td>#numberFormat(currentPercentage, '9.99')#%</td>
<td>#allLocCodeForLocationQry.locCntr#</td>
</tr>
</cfoutput>
</cfloop>
<tr>
<cfoutput>
<td><strong>Total</strong></td>
<td>#numberFormat(totalPercentage, '9.99')#%</td>
<td>#columnSum#</td>
</cfoutput>
</tr>
</tbody>
</table>
<cfcatch type="any">
<cfset result.error = CFCATCH.message >
<cfset result.detail = CFCATCH.detail >
</cfcatch>
</cftry>
</cfcontent>
</cfif>
Just add the following cfheader with a XLS-filename after cfcontent:
<cfheader name="Content-Disposition" value="yourfilename.xls">

CF sum of percentage column

I am having lots of trouble creating the sum of my percentage column which seems like it would be easy since its 100% when all branches are being shown. But I need to figure out the equation for the times that all branches are not shown. In the picture below each branches percentage is calculated by the number of that locations processed checklists divided by the total number of checklists. Unfortunately I can not figure out how to just "write" just adding the sum of the percentage column and displaying in into the total column. Any help would be greatly appreciated.
<cfset result = {} />
<cftry>
<cfquery datasource="#application.dsn#" name="GetLocationInfo">
SELECT *
FROM cl_checklists
</cfquery>
<cfquery name="allLocCode" dbtype="query">
SELECT DISTINCT trans_location, COUNT(*) AS locationCount FROM GetLocationInfo Where trans_location is not null GROUP BY trans_location ORDER BY trans_location
</cfquery>
<cfcatch type="any">
<cfset result.error = CFCATCH.message >
<cfset result.detail = CFCATCH.detail >
</cfcatch>
</cftry>
<cfset columnSum = ArraySum(allLocCode['locationCount'])>
<table border="1" id="Checklist_Stats">
<thead>
<th><strong>Location</strong></th>
<th><strong>Percent of Total Checklists</strong></th>
<th><strong>Location Total</strong></th>
</thead>
<tbody>
<cfloop query="allLocCode">
<cfset thisLocationName = trim(allLocCode.trans_location) />
<cfquery name="allLocCodeForLocationQry" dbtype="query">
SELECT trans_location,count(*) AS locCntr FROM GetLocationInfo WHERE trans_location='#thisLocationName#' GROUP BY trans_location ORDER BY trans_location
</cfquery>
<cfoutput query="allLocCodeForLocationQry">
<tr>
<td><strong>#thisLocationName#</strong></td>
<td>#NumberFormat((allLocCodeForLocationQry.locCntr/columnSum) * 100, '9.99')#%</td>
<td>#allLocCodeForLocationQry.locCntr#</td>
</tr>
</cfoutput>
</cfloop>
<cfdump var="#allLocCodeForLocationQry.locCntr#">
<tr>
<td><strong>Total</strong></td>
<td></td>
<td><cfoutput>#columnSum#</cfoutput></td>
</tr>
</tbody>
</table>
Unsure of how I can get the sum of this: <td>#NumberFormat((allLocCodeForLocationQry.locCntr/columnSum) * 100, '9.99')#%</td>
You can simply push the calculated percentage to an array and from there you can get the sum like this:
<!--- Define Array -->
<cfset checkListPercentage = arrayNew(1)>
<cfoutput query="allLocCodeForLocationQry">
<cfset currentPercentage = allLocCodeForLocationQry.locCntr / columnSum * 100)>
<cfset arrayAppend(checkListPercentage, currentPercentage)>
<tr>
<td><strong>#thisLocationName#</strong></td>
<td>#numberFormat(currentPercentage, '9.99')#%</td>
<td>#allLocCodeForLocationQry.locCntr#</td>
</tr>
</cfoutput>
<!--- Get Total --->
<cfoutput>#arraySum(checkListPercentage)#</cfoutput>
I've posted a somewhat similar answer before to one of these questions. This'll get you where you need to be:
Every time you get a percentage, you should set it as a variable and add it to a list or array. As an example for this chunk of code:
<cfloop query="allLocCode">
<cfset thisLocationName = trim(allLocCode.trans_location) />
<cfquery name="allLocCodeForLocationQry" dbtype="query">
SELECT trans_location,count(*) AS locCntr FROM GetLocationInfo WHERE trans_location='#thisLocationName#' GROUP BY trans_location ORDER BY trans_location
</cfquery>
<cfset PercentageList = "">
<cfset thisPercentage = #NumberFormat((allLocCodeForLocationQry.locCntr/columnSum) * 100, '9.99')#>
<cfset PercentageList = ListAppend(PercentageList, thisPercentage, ',')>
<cfoutput query="allLocCodeForLocationQry">
<tr>
<td><strong>#thisLocationName#</strong></td>
<td>#thisPercentage#%</td>
<td>#allLocCodeForLocationQry.locCntr#</td>
</tr>
</cfoutput>
</cfloop>
At the end of all your calculations, you should have a list of percentages. You can include this function to add the list together.
<cfscript>
function listSum(listStr)
{
var delim = ",";
if(ArrayLen(Arguments) GTE 2)
delim = Arguments[2];
return ArraySum(ListToArray(listStr, delim));
}
</cfscript>
So your last row would be:
<tr>
<td><strong>Total</strong></td>
<td>#listSum(PercentageList)#%</td>
<td><cfoutput>#columnSum#</cfoutput></td>
</tr>
Worth mentioning: Previously, it was pointed out to me that using Arrays and then converting to a List at the end of your calculations results in better performance, so that's something to keep in mind.
ArraySum is the relevant function for this.
With all the loops and queries inside other loops and queries, I just figured creating a list was a little easier.
E - unexplained downvotes are not nice.

CF Getting the sum of a column on a database query

I am trying to calculate the total of a column using ColdFusion and MS Sql.
Will someone please tell me what I am overlooking? My total for the location total is not doing the sum of the column but for somereason just taking the last number in that column. Where am I going wrong?
<cfset result = {} />
<cftry>
<cfquery datasource="#application.dsn#" name="GetLocationInfo">
SELECT *
FROM cl_checklists
</cfquery>
<cfcatch type="any">
<cfset result.error = CFCATCH.message >
<cfset result.detail = CFCATCH.detail >
</cfcatch>
</cftry>
<table border="1" id="Checklist_Stats">
<thead>
<th><strong>Location</strong></th>
<th><strong>Percent of Total Checklists</strong></th>
<th><strong>Location Total</strong></th>
</thead>
<tbody>
<cfquery name="allLocCode" dbtype="query">
SELECT DISTINCT trans_location, COUNT(*) AS locationCount FROM GetLocationInfo GROUP BY trans_location ORDER BY trans_location
</cfquery>
<cfloop query="allLocCode">
<cfset thisLocationName = trim(allLocCode.trans_location) />
<cfquery name="allLocCodeForLocationQry" dbtype="query">
SELECT trans_location,count(trans_location) AS locCntr FROM GetLocationInfo WHERE trans_location='#thisLocationName#' GROUP BY trans_location ORDER BY trans_location
</cfquery>
<cfset columnSum = ArraySum(allLocCodeForLocationQry['locCntr'])>
<cfoutput query="allLocCodeForLocationQry">
<tr>
<td><strong>#thisLocationName#</strong></td>
<td>#NumberFormat((allLocCodeForLocationQry.locCntr/allLocCode.locationCount) * 100, '9.99')#%</td>
<td>#allLocCodeForLocationQry.locCntr#</td>
</tr>
</cfoutput>
</cfloop>
<tr>
<td><strong>Total</strong></td>
<td></td>
<td><cfoutput>#numberFormat(columnSum)#</cfoutput></td>
</tr>
</tbody>
<!--- Total of All Sum of each column --->
</table>
Your columnSum variable is inside your cfloop. Put the <cfset columnSum = ArraySum(allLocCodeForLocationQry['locCntr'])> line outside of the cfloop (either before or after), and you should get your grand total of 334.
Try this.
Each time you loop through the query, append a value (the count of locations) to a list.
Something like this:
<cfset myList = "">
<cfloop query="allLocCode">
<cfset myList = ListAppend(myList, locationCount, ',')>
<!---your other logic--->
</cfloop>
At the end of your loop you should have a list of numbers as long as your query's recordcount.
You can add up all those numbers using this old function I found on CFLib.
<cfscript>
function listSum(listStr)
{
var delim = ",";
if(ArrayLen(Arguments) GTE 2)
delim = Arguments[2];
return ArraySum(ListToArray(listStr, delim));
}
</cfscript>
So, for example, if your final list was called myList and had values such as 14, 100, 7 - you would write out:
<cfoutput>#listSum(myList)#</cfoutput>
And get your final answer of 121.
Since this is sql server, why not take advantage of its ability to use the with keyword? The general idea is this:
with totalRecords as
(select count(*) records
from etc),
groupedRecords as
(select someField, count(*) recordsForField
from etc
group by someField)
select whatevever
, (groupedRecords.recordsForField / totalRecords.records) * 100 percentage
from someTables
join groupedRecords on groupedRecords.someField = someTable.someField
where totalRecords.records > 0
Then you simply output your query results.

CF Queries Calculating Percentages and adding the sum for a total line

I am trying to figure out how to run queries through a MS sql database using ColdFusion in order to make a table that keeps track of Location Name, Percent of Total Checklists, and Location Total.
I seem to be failing on calculating each branch locations percentage of checklists. I am trying to get the percent of each branch location and then create a sum total line that will add the total of all branches together.
This is what I have but for some reason I continue to get 100% for every location instead of showing each branches percentage and then show the total on the bottom.
Any help with this would be greatly appreciated!
<cfset result = {} />
<cftry>
<cfquery datasource="#application.dsn#" name="GetLocationInfo">
SELECT *
FROM cl_checklists
</cfquery>
<cfcatch type="any">
<cfset result.error = CFCATCH.message >
<cfset result.detail = CFCATCH.detail >
</cfcatch>
</cftry>
<table border="1" id="Checklist_Stats">
<thead>
<th><strong>Location</strong></th>
<th><strong>Percent of Total Checklists</strong></th>
<th><strong>Location Total</strong></th>
</thead>
<tbody>
<cfquery name="allLocCode" dbtype="query">
SELECT DISTINCT trans_location, COUNT(*) AS locationCount FROM GetLocationInfo GROUP BY trans_location ORDER BY trans_location
</cfquery>
<cfloop query="allLocCode">
<cfset thisLocationName = trim(allLocCode.trans_location) />
<cfquery name="allLocCodeForLocationQry" dbtype="query">
SELECT trans_location,count(trans_location) AS locCntr FROM GetLocationInfo WHERE trans_location='#thisLocationName#' GROUP BY trans_location ORDER BY trans_location
</cfquery>
<cfoutput query="allLocCodeForLocationQry">
<tr>
<td><strong>#thisLocationName#</strong></td>
<td>#NumberFormat((allLocCodeForLocationQry.locCntr/allLocCode.locationCount) * 100, '9.99')#%</td>
<td>#allLocCodeForLocationQry.locCntr#</td>
</tr>
</cfoutput>
</cfloop>
</tbody>
<!--- Total of All Sum of each column --->
<tr>
<td><strong>Total</strong></td>
<td></td>
<td></td>
</tr>
</table>
Regarding I am trying to get the percent of each branch location and then create a sum total line that will add the total of all branches together., array functions work on query columns. The syntax, is:
columnSum = ArraySum(queryName['columnName']