CF SQL Creating a Table with different results - coldfusion

I am trying to create a table using coldfusion and sql. The table I am trying to create looks like this:
<cfquery datasource="#application.dsn#" name="someprocessTable">
SELECT *
FROM checklists
</cfquery>
<table id="Checklist_Stats">
<thead>
<th><b>Associate Name</b></th>
<th><b>Location</b></th>
<th><b>Checklists Generated by Associate</b></th>
<th><b>Checklists Generated by Selected Location(s)</b></th>
<th><b>Associate Percentage of Location Total</b></th>
</thead>
<tbody>
<cfoutput query="someprocessTable">
<tr>
<td>#associate#</td>
<td>#location_code#</td>
<td>#associate.recordcount#</td>
<!---<td>##</td>
<td>##</td>--->
</tr>
</cfoutput>
</tbody>
</table>
The part I am unsure about is how do I loop all of this information under one table? Because you would not want to have the same persons name keep reoccurring on the table and then how do you show how many was generated by them since I could not do something like #associate.recordcount#

There seems more than one way to do what you want to achieve like doing a query with joins and groups then dump in table; manage your output with a single CFoutput or use nested CFOutput and/or CFloop.
Following show third approach:
<table border="1" id="Checklist_Stats">
<thead>
<th><b>Associate Name</b></th>
<th><b>Location</b></th>
<th><b>Checklists Generated by Associate</b></th>
<th><b>Checklists Generated by Selected Location(s)</b></th>
<th><b>Associate Percentage of Location Total</b></th>
</thead>
<tbody>
<cfquery name="allAssociatesQry" dbtype="query">
SELECT DISTINCT associate, COUNT(*) AS associateCount FROM someprocessTable GROUP BY associate ORDER BY associate
</cfquery>
<cfloop query="allAssociatesQry">
<cfquery name="allLocCodeForAssociateQry" dbtype="query">
SELECT * FROM someprocessTable WHERE associate='#associate#' ORDER BY location_code
</cfquery>
<tr><td><cfoutput>#allLocCodeForAssociateQry.associate#</cfoutput></td>
<cfoutput query="allLocCodeForAssociateQry" group="location_code">
<cfset locCntr = 0 />
<cfoutput>
<cfset locCntr = locCntr + 1 />
</cfoutput>
<cfif allLocCodeForAssociateQry.currentRow NEQ 1>
<tr><td> </td>
</cfif>
<td>#allLocCodeForAssociateQry.location_code#</td>
<td>#allAssociatesQry.associateCount#</td>
<td>#locCntr#</td>
<td>#Round((locCntr/allAssociatesQry.associateCount) * 100)#%</td>
</tr>
</cfoutput>
</cfloop>
</tbody>
</table>
Please note that CF QoQ is case sensitive so if need be then convert associate name and location to lower/upper/title case before hand
A slightly modified code for the CFloop may be like below:
<cfloop query="allAssociatesQry">
<cfset thisAssociateName = trim(allAssociatesQry.associate) />
<cfquery name="allLocCodeForAssociateQry" dbtype="query">
SELECT location_code,count(location_code) AS locCntr FROM someprocessTable WHERE associate='#thisAssociateName#' GROUP BY location_code ORDER BY location_code
</cfquery>
<cfoutput query="allLocCodeForAssociateQry">
<tr>
<td>#thisAssociateName#</td>
<td>#allLocCodeForAssociateQry.location_code#</td>
<td>#allAssociatesQry.associateCount#</td>
<td>#allLocCodeForAssociateQry.locCntr#</td>
<td>#Round((allLocCodeForAssociateQry.locCntr/allAssociatesQry.associateCount) * 100)#%</td>
</tr>
<cfset thisAssociateName = "" />
</cfoutput>
</cfloop>

Related

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 query remove empty string results for total sum

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.

CF Location queries looping issue

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, Percent of Total Checklists, and Location Total.
I am having trouble looping to show my locations only once and to run the totals for each location. I am not sure why my table is adding all of these lines like the picture below, 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 locCntr FROM GetLocationInfo GROUP BY trans_location ORDER BY trans_location
</cfquery>
<cfloop query="allLocCode">
<cfset thisLocationName = trim(allLocCode.trans_location) />
<cfoutput query="allLocCode">
<tr>
<td><strong>#thisLocationName#</strong></td>
<td></td>
<td></td>
</tr>
<cfset thisLocationName = "" />
</cfoutput>
</cfloop>
</tbody>
<!--- Total of All Sum of each column --->
<tr>
<td><strong>Total</strong></td>
<td></td>
<td></td>
</tr>
</table>
You only need to loop through the query once. Remove the additional cfoutput
<cfoutput query="allLocCode">
<cfset thisLocationName = trim(allLocCode.trans_location) />
<tr>
<td><strong>#thisLocationName#</strong></td>
<td></td>
<td></td>
</tr>
</cfoutput>
Your code creates a nested loop.
<cfloop query="allLocCode"> // loop over all items in the query
<cfset thisLocationName = trim(allLocCode.trans_location) />
<cfoutput query="allLocCode"> // loop again over all items in the query
<tr>
<td><strong>#thisLocationName#</strong></td> // print the string
<td></td>
<td></td>
</tr>
<cfset thisLocationName = "" /> // empties the string, hence next rows will be empty
</cfoutput>
</cfloop>
Change the line <cfoutput query="allLocCode"> to <cfoutput>.

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']

how to loop through Query Columns in ColdFusion

I have a query in a my CFC. The function contains a simple query as such.
<cfquery name="qrySE" datasource=#mydatasource#>
SELECT
NAMES,SALARY
FROM tblTest
</cfquery>
I want to display my resultset as such (horizontally):
NAME1 NAME2 NAME3 NAME4
10 20 45 62
Is there a way to loop through the columns of my query and create a virtual query for this purpose?
If anyone has done this, please let me know.
Just wanted to add Al Everett's solution returns the columns back in alphabetical order. If you would like to get the column names back in the same order as the query you can use:
ArrayToList( qrySE.getColumnNames() )
which I found here: http://www.richarddavies.us/archives/2009/07/cf_columnlist.php
you can use this to create a function to output queries to a table like this:
<cffunction name="displayQueryAsTable" output="true">
<cfargument name="rawQueryObject" type="query" required="true">
<table >
<tr>
<cfloop list="#ArrayToList(rawQueryObject.getColumnNames())#" index="col" >
<th>#col#</th>
</cfloop>
</tr>
<cfloop query="rawQueryObject">
<tr>
<cfloop list="#ArrayToList(rawQueryObject.getColumnNames())#" index="col">
<td>#rawQueryObject[col][currentrow]#</td>
</cfloop>
</tr>
</cfloop>
</table>
</cffunction>
You could use the built-in query.columnList that is returned with each query. (It's metadata of the query, like recordCount.)
You could do something like this:
<table>
<cfloop list="#qrySE.columnList#" index="col">
<tr>
<cfloop query="qrySE">
<td>#qrySE[col][currentRow]#</td>
</cfloop>
</tr>
</cfloop>
</table>
Not tested, but that should give you the idea.