Search code examples
mysqlloopscoldfusioncoldfusion-8addition

CF8 - Sum in a loop


I have a query:

<cfquery name="getDesc" datasource="#ds#">
  SELECT
    desc,
    SUM(charge) as cost,
    COUNT(*) as cnt
  FROM
    product
  WHERE Length(desc) > 0
</cfquery>

Which then populates a table:

<table>
  <tbody>
      <tr>
        <th>Description</th>
        <th>Amount of Charges</th>
        <th>Cost (&pound;)</th>
      </tr>

      <cfoutput query="getDesc">
      <tr>
        <td>
          #HTMLEditFormat(getDesc.desc)# <br />
        </td>     
        <td>
          #HTMLEditFormat(getDesc.cnt)# <br />
        </td>
        <td>
            #HTMLEditFormat(getDesc.cost)# <br />
        </td>
      </tr>
    </cfoutput>
  </tbody>
</table>

My problem is that I'd like to combine two rows of the table that have the same value and also have both of their counts added together.

So far I have:

<table>
  <tbody>
      <tr>
        <th>Description</th>
        <th>Amount of Charges</th>
        <th>Cost (&pound;)</th>
      </tr>

      <cfoutput query="getDesc">
      <tr>
        <cfif getDesc.desc EQ 'No Charge' OR getDesc.desc EQ 'No Charge (2)'>
          <td>
            No Charge & (2)
          </td>
          <td>
            <cfset cntSum = arraySum(getDesc['cnt'])>
            #cntSum#
          </td>
        <cfelse>
        <td>
          #HTMLEditFormat(getDesc.desc)# <br />
        </td>     
        <td>
          #HTMLEditFormat(getDesc.cnt)# <br />
        </td>
        </cfif>
        <td>
            #HTMLEditFormat(getDesc.cost)# <br />
        </td>
      </tr>
    </cfoutput>
  </tbody>
</table>

But this gives me two rows of 'No Charge & (2)' and the count is the sum of all the rest of the rows in the table rather than just the two rows I want.

Hope this makes sense.


Solution

  • I would change your query around to get you the data you need. Here's what I've just whipped up which I think would meet your requirement:

      SELECT
        CASE `desc` WHEN 'No Charge (2)' THEN 'No Charge' ELSE `desc` END,
        SUM(charge) as cost,
        COUNT(*) as cnt
      FROM
        product
      WHERE Length(`desc`) > 0
      group by CASE `desc` WHEN 'No Charge (2)' THEN 'No Charge' ELSE `desc` END
    

    The case statement is changing 'No Charge (2)' into 'No Charge' so there's only one row for both kinds of values. The group by statement is making mySQL perform the sum and count once per different value of 'desc'.