ColdFusion Query Of Queries Odd COUNT(*) Behavior

Posted September 7, 2006 at 10:59 AM

Tags: ColdFusion

If you ever run a COUNT(*) aggregate in a SQL SELECT statement, you will know that it returns the number of records that match your select criteria. If 14 records match, it returns 14. If zero records match, it returns zero. This behavior, however, is corrupted when it comes to ColdFusion query of queries.

As always, let's start by building a query against which to run tests:

 Launch code in new window » Download code as text file »

  • <!--- Set up a query for girls. --->
  • <cfset qGirls = QueryNew( "id, name, hotness, hair" ) />
  •  
  • <!--- Add some rows to the query. --->
  • <cfset QueryAddRow( qGirls, 4 ) />
  •  
  • <!--- Set data values. --->
  • <cfset qGirls[ "id" ][ 1 ] = 1 />
  • <cfset qGirls[ "name" ][ 1 ] = "Libby" />
  • <cfset qGirls[ "hotness" ][ 1 ] = 8.5 />
  • <cfset qGirls[ "hair" ][ 1 ] = "Brunette" />
  •  
  • <cfset qGirls[ "id" ][ 2 ] = 2 />
  • <cfset qGirls[ "name" ][ 2 ] = "Yuu" />
  • <cfset qGirls[ "hotness" ][ 2 ] = 7.5 />
  • <cfset qGirls[ "hair" ][ 2 ] = "Black" />
  •  
  • <cfset qGirls[ "id" ][ 3 ] = 3 />
  • <cfset qGirls[ "name" ][ 3 ] = "Kim" />
  • <cfset qGirls[ "hotness" ][ 3 ] = 7.5 />
  • <cfset qGirls[ "hair" ][ 3 ] = "Brunette" />
  •  
  • <cfset qGirls[ "id" ][ 4 ] = 4 />
  • <cfset qGirls[ "name" ][ 4 ] = "Molly" />
  • <cfset qGirls[ "hotness" ][ 4 ] = 10.0 />
  • <cfset qGirls[ "hair" ][ 4 ] = "Brunette" />

Now that we have our girls set up, let's query our query to find the number hot girls we have. For this test, our definition of hot will be those girls with a hotness rating of 8 or higher.

 Launch code in new window » Download code as text file »

  • <!---
  • Now, get the number of girls that have a hotness
  • over 8. That's really hot.
  • --->
  • <cfquery name="qHotGirls" dbtype="query">
  • SELECT
  • COUNT( * ) AS girl_count
  • FROM
  • qGirls
  • WHERE
  • hotness > 8
  • </cfquery>

As you can see, all we are doing is selecting the COUNT( * ) on the query. Dumping out the results, we find we have two hot girls, just as can be expected:


 
 
 

 
CFDump qHotGirls - COUNT(*) Demo  
 
 
 

Now, let's query our query to find the number of not-so-hot girls. For this test, our definition of not-so-hot will be those girls with a hotness rating less than 5.

 Launch code in new window » Download code as text file »

  • <!---
  • Now, get the number of girls that have a hotness
  • under 5. That's not so hot.
  • --->
  • <cfquery name="qNotSoHotGirls" dbtype="query">
  • SELECT
  • COUNT( * ) AS girl_count
  • FROM
  • qGirls
  • WHERE
  • hotness < 5
  • </cfquery>

Again, we are just getting the number of girls as a COUNT aggregate. As we had no not-so-hot girls in the original query, we would expect to get a record with the value zero (0). Dumping out the results, though, you will see that in fact, we have no records at all:


 
 
 

 
CFDump qNotSoHotGirls - COUNT(*) Demo  
 
 
 

This is bizarre and can be a hassle in your programming. Now, just to make sure that I am not going crazy, I am going to do a control test against a regular SQL database to see how it works:

 Launch code in new window » Download code as text file »

  • <cfquery name="qControlTest" datasource="...">
  • SELECT
  • COUNT( * ) AS record_count
  • FROM
  • blog_entry
  • WHERE
  • <!--- This ensures that no records will be returned. --->
  • 1 = 0
  • </cfquery>

This query is designed to NEVER return anything but zero as the count. And, from the following dump, you will see that this is in fact how a COUNT aggregate in the SQL DB works:


 
 
 

 
CFDump qControlTest - COUNT(*) Demo  
 
 
 

Now, as I mentioned, this can be somewhat irritating to deal with in the code. The easiest solution to work with is to simply check to see if any records were returned, and, if no records were returned, create one manually with a default value:

 Launch code in new window » Download code as text file »

  • <!--- Check to see if any records were returned. --->
  • <cfif NOT qNotSoHotGirls.RecordCount>
  •  
  • <!--- Set default values for aggregates. --->
  • <cfset QueryAddRow( qNotSoHotGirls, 1 ) />
  • <cfset qNotSoHotGirls[ "girl_count" ][ 1 ] = 0 />
  •  
  • </cfif>

This way, you can carry on with the programming and not have to take any special considerations just because you were performing a query of queries rather than querying a database.

Download Code Snippet ZIP File

Post Comment  |  Ask Ben  |  Other Searches  |  Print Page



Learning ColdFusion 9 - ColdFusion 9 tutorials, samples, examples, demos

Reader Comments

Feb 4, 2008 at 12:16 PM // reply »
1 Comments

nasty example


Dec 9, 2009 at 5:40 AM // reply »
1 Comments

this might be hugely off topic, but I have made a search form with several dropdown boxes, I would like that if no results match the search (if the query returns no records) the user gets a line of text saying something in the lines of "Your search returned no results, please try changing your criteria", could you possibly let me know how I would go about doing this?


Post Comment  |  Ask Ben

Recent Blog Comments
Mar 21, 2010 at 6:32 AM
ColdFusion CFPOP - My First Look
Apologies... The field name in the db for C. is "BounceCode" It stores the code / message which is returned in the email. Sorry for the confusion. ... read »
Mar 21, 2010 at 6:29 AM
ColdFusion CFPOP - My First Look
@Jose Galdamez, Hi Ben and Jose 1st of all.. big thanks to Jose for his Skype chat a few weeks back. Your time was much appreciated. I have come up with a rather unelegant solution to my problem a ... read »
Mar 21, 2010 at 3:42 AM
A New Wrist Pain
Chiropractic treatment is one of the best methods for treating numerous health problems naturally. After years of experience being a chiropractor, I have found that it is a powerful way to solve many ... read »
Mar 20, 2010 at 12:07 PM
Drawing On The iPhone Canvas With jQuery And ColdFusion
Simply awesome. Saved my day. ... read »
Mar 20, 2010 at 9:00 AM
Building A Fixed-Position Bottom Menu Bar (ala FaceBook)
I would like to say thx for an easy way to create a bottom bar. I do have a ?. Is it possible to center the bar if i want to resize it to ex 85%. Regards Offenbach ... read »
Mar 19, 2010 at 7:26 PM
MySQL 3/4 - com.mysql.jdbc.Driver And allowMultiQueries=true
Thank you very much for this post. Adding allowMultiQueries="true" in context.xml didn't help until I added it to url as allowMultiQueries=true Good idea is to use prepared statements and it will he ... read »
Jim
Mar 19, 2010 at 4:49 PM
Nobody Puts Baby In The Corner!
Wow. This is like suddenly finding a support group for your secret shame. I'm not alone! I always liked this movie, even though it is extremely cheesy. I just wish Jennifer Grey hadn't gotten the ... read »
Mar 19, 2010 at 4:47 PM
Application.cfc OnRequest() Method Affects OnError() Arguments
@Jason and @Ben, I've been doing some CF9 refactoring on our systems and noticed an odd occurrence with onError as well. Found a way to work around my problem, but what I saw was... Background: Our ... read »