首页 > 解决方案 > Coldfusion计数来自多个数据源的循环查询结果

问题描述

包含多个数据源的列表循环中的查询会从每个数据源生成记录。我想建立一个唯一的部门列表,并计算部门在循环数据源时出现的次数。

这是有效的,但有没有更好的方法使用数组或结构?

<cfset divisions = "">

<!--- within query within loop --->

<cfif ListContains(divisions, "#SearchCompanyList.Division#")>
    <cfset variables['division#SearchCompanyList.Division#'] = variables['division#SearchCompanyList.Division#'] + 1>
<cfelse>
    <cfif Len(SearchCompanyList.Division) gt 0>
        <cfset divisions = ListAppend(divisions, "#SearchCompanyList.Division#")>
        <cfset variables['division#SearchCompanyList.Division#'] = 0>
    </cfif>
</cfif>

<!--- outside of query and loop --->

<cfloop list="#divisions#" index="div">
    <cfoutput>#div#: #Evaluate('division'&div)#</cfoutput>
</cfloop>

标签: arraysstructcoldfusion

解决方案


您正在做太多的变量间接。摆脱所有variables["#variablename#"]Evaluate(),所有这些都是不必要的。这适用于您的其余代码,我敢打赌您可以大大简化它。

对于您的主要问题,请使用结构:

<cfset divisionCount = StructNew('casesensitive')>

<cfloop query="SearchCompanyList">
    <cfif StructKeyExists(divisionCount, Division)>
        <cfset divisionCount[Division]++>
    <cfelse>
        <cfset divisionCount[Division] = 1>
    </cfif>
</cfloop>

<cfoutput>
<cfloop array="#StructKeyArray(divisionCount)#" item="div">
    #encodeForHTML(div)#: #divisionCount[div]#<br>
</cfloop>
</cfoutput>

StructNew('casesensitive')从 CF2021 开始支持。如果您还没有那个版本,ColdFusion 会将结构键大写。使用第二个结构来存储原始分区名称,以便您可以正确输出它们:

<cfset divisionCount = StructNew()>
<cfset divisionName = StructNew()>

<cfloop query="SearchCompanyList">
    <cfif StructKeyExists(divisionCount, Division)>
        <cfset divisionCount[Division]++>
    <cfelse>
        <cfset divisionCount[Division] = 1>
        <cfset divisionName[Division] = Division>
    </cfif>
</cfloop>

<cfoutput>
<cfloop array="#StructKeyArray(divisionCount)#" item="div">
    #encodeForHTML(divisionName[div])#: #divisionCount[div]#<br>
</cfloop>
</cfoutput>

对于多列的并排计数,具有更高级 CF 的可重用选项将是:

<cfscript>
function toGroupsBy(column) {
  return function (result, row) {
    var value = row[column];
    if (result.keyExists(value)) result[value][2]++; else result[value] = [value, 1];
    return result;
  };
}
</cfscript>

<cfset byDivision = SearchCompanyList.reduce(toGroupsBy('Division'), {})>
<cfset bySalesPerson = SearchCompanyList.reduce(toGroupsBy('SalesPerson'), {})>

<cfdump var="#byDivision#" label="Grouped by Division">
<cfdump var="#bySalesPerson#" label="Grouped by SalesPerson">

<cfoutput>
<cfloop array="#StructKeyArray(byDivision)#" item="div">
    #encodeForHTML(byDivision[div][1])#: #byDivision[div][2]#<br>
</cfloop>
</cfoutput>

对于嵌套计数,我实际上会使用 ColdFusion 的本机输出分组机制。正确排序查询对于此工作是必要的。注意嵌套<cfoutput>标签。

<cfquery name="SearchCompanyList" datasource="mydb">
  SELECT
    Division, SalesPerson
  FROM
    MyTable 
  ORDER BY
    Division, SalesPerson
</cfquery>

<cfoutput query="SearchCompanyList" group="Division">
  <cfset divCount = 0>
  <h3>#encodeForHTML(Division)#</h3>
  <ul>
    <cfoutput group="SalesPerson">
      <cfset persCount = 0>
      <cfoutput>
        <cfset persCount++>
        <cfset divCount++>
      </cfoutput>
      <li>#encodeForHTML(SalesPerson)#: #persCount#</li>
    </cfoutput>
    <li><b>Overall</b>: #divCount#</li>
  </ul>
</cfoutput>

推荐阅读